在二叉树中计算总和等于给定值x
的偶对数量
原文:https://www.geeksforgeeks.org/count-pairs-in-a-binary-tree-whose-sum-is-equal-to-a-given-value-x/
给定一个包含n
个不同数字和值x
的二叉树。 问题在于在给定的二叉树中对它们的总和等于给定值x
的对进行计数。
示例:
Input :
5
/ \
3 7
/ \ / \
2 4 6 8
x = 10
Output : 3
The pairs are (3, 7), (2, 8) and (4, 6).
1)朴素的方法:通过任何一种树遍历方法逐一获取二叉树的每个节点。 将节点temp
,树的根和值x
传递给另一个函数,例如findPair()
。 在函数中,借助根指针再次遍历树。 将这些节点与temp
逐一求和,并检查sum == x
。 如果是这样,则递增count
。 计算count /= 2
,因为通过上述方法已对一对进行了两次计数。
C++
// C++ implementation to count pairs in a binary tree
// whose sum is equal to given value x
#include <bits/stdc++.h>
using namespace std;
// structure of a node of a binary tree
struct Node {
int data;
Node *left, *right;
};
// function to create and return a node
// of a binary tree
Node* getNode(int data)
{
// allocate space for the node
Node* new_node = (Node*)malloc(sizeof(Node));
// put in the data
new_node->data = data;
new_node->left = new_node->right = NULL;
}
// returns true if a pair exists with given sum 'x'
bool findPair(Node* root, Node* temp, int x)
{
// base case
if (!root)
return false;
// pair exists
if (root != temp && ((root->data + temp->data) == x))
return true;
// find pair in left and right subtress
if (findPair(root->left, temp, x) || findPair(root->right, temp, x))
return true;
// pair does not exists with given sum 'x'
return false;
}
// function to count pairs in a binary tree
// whose sum is equal to given value x
void countPairs(Node* root, Node* curr, int x, int& count)
{
// if tree is empty
if (!curr)
return;
// check whether pair exists for current node 'curr'
// in the binary tree that sum up to 'x'
if (findPair(root, curr, x))
count++;
// recursively count pairs in left subtree
countPairs(root, curr->left, x, count);
// recursively count pairs in right subtree
countPairs(root, curr->right, x, count);
}
// Driver program to test above
int main()
{
// formation of binary tree
Node* root = getNode(5); /* 5 */
root->left = getNode(3); /* / \ */
root->right = getNode(7); /* 3 7 */
root->left->left = getNode(2); /* / \ / \ */
root->left->right = getNode(4); /* 2 4 6 8 */
root->right->left = getNode(6);
root->right->right = getNode(8);
int x = 10;
int count = 0;
countPairs(root, root, x, count);
count = count / 2;
cout << "Count = " << count;
return 0;
}
Java
// Java implementation to count pairs in a binary tree
// whose sum is equal to given value x
import java.util.*;
class GFG
{
// structure of a node of a binary tree
static class Node
{
int data;
Node left, right;
};
static int count;
// function to create and return a node
// of a binary tree
static Node getNode(int data)
{
// allocate space for the node
Node new_node = new Node();
// put in the data
new_node.data = data;
new_node.left = new_node.right = null;
return new_node;
}
// returns true if a pair exists with given sum 'x'
static boolean findPair(Node root, Node temp, int x)
{
// base case
if (root==null)
return false;
// pair exists
if (root != temp && ((root.data + temp.data) == x))
return true;
// find pair in left and right subtress
if (findPair(root.left, temp, x) ||
findPair(root.right, temp, x))
return true;
// pair does not exists with given sum 'x'
return false;
}
// function to count pairs in a binary tree
// whose sum is equal to given value x
static void countPairs(Node root, Node curr, int x)
{
// if tree is empty
if (curr == null)
return;
// check whether pair exists for current node 'curr'
// in the binary tree that sum up to 'x'
if (findPair(root, curr, x))
count++;
// recursively count pairs in left subtree
countPairs(root, curr.left, x);
// recursively count pairs in right subtree
countPairs(root, curr.right, x);
}
// Driver code
public static void main(String[] args)
{
// formation of binary tree
Node root = getNode(5); /* 5 */
root.left = getNode(3); /* / \ */
root.right = getNode(7); /* 3 7 */
root.left.left = getNode(2); /* / \ / \ */
root.left.right = getNode(4); /* 2 4 6 8 */
root.right.left = getNode(6);
root.right.right = getNode(8);
int x = 10;
count = 0;
countPairs(root, root, x);
count = count / 2;
System.out.print("Count = " + count);
}
}
// This code is contributed by PrinciRaj1992
Python3
# Python3 implementation to count pairs in a binary tree
# whose sum is equal to given value x
# structure of a node of a binary tree
class getNode(object):
def __init__(self, value):
self.data = value
self.left = None
self.right = None
# returns True if a pair exists with given sum 'x'
def findPair(root, temp, x):
# base case
if root == None:
return False
# pair exists
if (root != temp and ((root.data + temp.data) == x)):
return True
# find pair in left and right subtress
if (findPair(root.left, temp, x) or findPair(root.right, temp, x)):
return True
# pair does not exists with given sum 'x'
return False
# function to count pairs in a binary tree
# whose sum is equal to given value x
def countPairs(root, curr, x):
global count
# if tree is empty
if curr == None:
return
# check whether pair exists for current node 'curr'
# in the binary tree that sum up to 'x'
if (findPair(root, curr, x)):
count += 1
# recursively count pairs in left subtree
countPairs(root, curr.left, x)
# recursively count pairs in right subtree
countPairs(root, curr.right, x)
# Driver program to test above
# formation of binary tree
root = getNode(5)
root.left = getNode(3)
root.right = getNode(7)
root.left.left = getNode(2)
root.left.right = getNode(4)
root.right.left = getNode(6)
root.right.right = getNode(8)
x = 10
count = 0
countPairs(root, root, x)
count = count // 2
print("Count =", count)
# This code is contributed by shubhamsingh10
C
// C# implementation to count pairs in a binary tree
// whose sum is equal to given value x
using System;
class GFG
{
// structure of a node of a binary tree
class Node
{
public int data;
public Node left, right;
};
static int count;
// function to create and return a node
// of a binary tree
static Node getNode(int data)
{
// allocate space for the node
Node new_node = new Node();
// put in the data
new_node.data = data;
new_node.left = new_node.right = null;
return new_node;
}
// returns true if a pair exists with given sum 'x'
static bool findPair(Node root, Node temp, int x)
{
// base case
if (root == null)
return false;
// pair exists
if (root != temp && ((root.data + temp.data) == x))
return true;
// find pair in left and right subtress
if (findPair(root.left, temp, x) ||
findPair(root.right, temp, x))
return true;
// pair does not exists with given sum 'x'
return false;
}
// function to count pairs in a binary tree
// whose sum is equal to given value x
static void countPairs(Node root, Node curr, int x)
{
// if tree is empty
if (curr == null)
return;
// check whether pair exists for current node 'curr'
// in the binary tree that sum up to 'x'
if (findPair(root, curr, x))
count++;
// recursively count pairs in left subtree
countPairs(root, curr.left, x);
// recursively count pairs in right subtree
countPairs(root, curr.right, x);
}
// Driver code
public static void Main(String[] args)
{
// formation of binary tree
Node root = getNode(5); /* 5 */
root.left = getNode(3); /* / \ */
root.right = getNode(7); /* 3 7 */
root.left.left = getNode(2); /* / \ / \ */
root.left.right = getNode(4); /* 2 4 6 8 */
root.right.left = getNode(6);
root.right.right = getNode(8);
int x = 10;
count = 0;
countPairs(root, root, x);
count = count / 2;
Console.Write("Count = " + count);
}
}
// This code is contributed by Rajput-Ji
输出:
Count = 3
时间复杂度:O(N ^ 2)
。
2)高效方法:
以下是步骤:
C++
// C++ implementation to count pairs in a binary tree
// whose sum is equal to given value x
#include <bits/stdc++.h>
using namespace std;
// structure of a node of a binary tree
struct Node {
int data;
Node *left, *right;
};
// function to create and return a node
// of a binary tree
Node* getNode(int data)
{
// allocate space for the node
Node* new_node = (Node*)malloc(sizeof(Node));
// put in the data
new_node->data = data;
new_node->left = new_node->right = NULL;
}
// A simple recursive function to convert a given
// Binary tree to Doubly Linked List
// root --> Root of Binary Tree
// head_ref --> Pointer to head node of created
// doubly linked list
void BToDLL(Node* root, Node** head_ref)
{
// Base cases
if (root == NULL)
return;
// Recursively convert right subtree
BToDLL(root->right, head_ref);
// insert root into DLL
root->right = *head_ref;
// Change left pointer of previous head
if (*head_ref != NULL)
(*head_ref)->left = root;
// Change head of Doubly linked list
*head_ref = root;
// Recursively convert left subtree
BToDLL(root->left, head_ref);
}
// Split a doubly linked list (DLL) into 2 DLLs of
// half sizes
Node* split(Node* head)
{
Node *fast = head, *slow = head;
while (fast->right && fast->right->right) {
fast = fast->right->right;
slow = slow->right;
}
Node* temp = slow->right;
slow->right = NULL;
return temp;
}
// Function to merge two sorted doubly linked lists
Node* merge(Node* first, Node* second)
{
// If first linked list is empty
if (!first)
return second;
// If second linked list is empty
if (!second)
return first;
// Pick the smaller value
if (first->data < second->data) {
first->right = merge(first->right, second);
first->right->left = first;
first->left = NULL;
return first;
}
else {
second->right = merge(first, second->right);
second->right->left = second;
second->left = NULL;
return second;
}
}
// Function to do merge sort
Node* mergeSort(Node* head)
{
if (!head || !head->right)
return head;
Node* second = split(head);
// Recur for left and right halves
head = mergeSort(head);
second = mergeSort(second);
// Merge the two sorted halves
return merge(head, second);
}
// Function to count pairs in a sorted doubly linked list
// whose sum equal to given value x
int pairSum(Node* head, int x)
{
// Set two pointers, first to the beginning of DLL
// and second to the end of DLL.
Node* first = head;
Node* second = head;
while (second->right != NULL)
second = second->right;
int count = 0;
// The loop terminates when either of two pointers
// become NULL, or they cross each other (second->right
// == first), or they become same (first == second)
while (first != NULL && second != NULL && first != second && second->right != first) {
// pair found
if ((first->data + second->data) == x) {
count++;
// move first in forward direction
first = first->right;
// move second in backward direction
second = second->left;
}
else {
if ((first->data + second->data) < x)
first = first->right;
else
second = second->left;
}
}
return count;
}
// function to count pairs in a binary tree
// whose sum is equal to given value x
int countPairs(Node* root, int x)
{
Node* head = NULL;
int count = 0;
// Convert binary tree to
// doubly linked list
BToDLL(root, &head);
// sort DLL
head = mergeSort(head);
// count pairs
return pairSum(head, x);
}
// Driver program to test above
int main()
{
// formation of binary tree
Node* root = getNode(5); /* 5 */
root->left = getNode(3); /* / \ */
root->right = getNode(7); /* 3 7 */
root->left->left = getNode(2); /* / \ / \ */
root->left->right = getNode(4); /* 2 4 6 8 */
root->right->left = getNode(6);
root->right->right = getNode(8);
int x = 10;
cout << "Count = "
<< countPairs(root, x);
return 0;
}
Java
// Java implementation to count pairs
// in a binary tree whose sum is equal to
// given value x
class GFG
{
// structure of a node of a binary tree
static class Node
{
int data;
Node left, right;
};
static Node head_ref;
// function to create and return a node
// of a binary tree
static Node getNode(int data)
{
// allocate space for the node
Node new_node = new Node();
// put in the data
new_node.data = data;
new_node.left = new_node.right = null;
return new_node;
}
// A simple recursive function to convert
// a given Binary tree to Doubly Linked List
// root -. Root of Binary Tree
// head_ref -. Pointer to head node of created
// doubly linked list
static void BToDLL(Node root)
{
// Base cases
if (root == null)
return;
// Recursively convert right subtree
BToDLL(root.right);
// insert root into DLL
root.right = head_ref;
// Change left pointer of previous head
if (head_ref != null)
head_ref.left = root;
// Change head of Doubly linked list
head_ref = root;
// Recursively convert left subtree
BToDLL(root.left);
}
// Split a doubly linked list (DLL)
// into 2 DLLs of half sizes
static Node split(Node head)
{
Node fast = head, slow = head;
while (fast.right != null &&
fast.right.right != null)
{
fast = fast.right.right;
slow = slow.right;
}
Node temp = slow.right;
slow.right = null;
return temp;
}
// Function to merge two sorted
// doubly linked lists
static Node merge(Node first, Node second)
{
// If first linked list is empty
if (first == null)
return second;
// If second linked list is empty
if (second == null)
return first;
// Pick the smaller value
if (first.data < second.data)
{
first.right = merge(first.right,
second);
first.right.left = first;
first.left = null;
return first;
}
else
{
second.right = merge(first,
second.right);
second.right.left = second;
second.left = null;
return second;
}
}
// Function to do merge sort
static Node mergeSort(Node head)
{
if (head == null || head.right == null)
return head;
Node second = split(head);
// Recur for left and right halves
head = mergeSort(head);
second = mergeSort(second);
// Merge the two sorted halves
return merge(head, second);
}
// Function to count pairs in a sorted
// doubly linked list whose sum equal
// to given value x
static int pairSum(Node head, int x)
{
// Set two pointers, first to the beginning
// of DLL and second to the end of DLL.
Node first = head;
Node second = head;
while (second.right != null)
second = second.right;
int count = 0;
// The loop terminates when either of two pointers
// become null, or they cross each other (second.right
// == first), or they become same (first == second)
while (first != null && second != null &&
first != second && second.right != first)
{
// pair found
if ((first.data + second.data) == x)
{
count++;
// move first in forward direction
first = first.right;
// move second in backward direction
second = second.left;
}
else
{
if ((first.data + second.data) < x)
first = first.right;
else
second = second.left;
}
}
return count;
}
// function to count pairs in a binary tree
// whose sum is equal to given value x
static int countPairs(Node root, int x)
{
head_ref = null;
// Convert binary tree to
// doubly linked list
BToDLL(root);
// sort DLL
head_ref = mergeSort(head_ref);
// count pairs
return pairSum(head_ref, x);
}
// Driver Code
public static void main(String[] args)
{
// formation of binary tree
Node root = getNode(5); /* 5 */
root.left = getNode(3); /* / \ */
root.right = getNode(7); /* 3 7 */
root.left.left = getNode(2); /* / \ / \ */
root.left.right = getNode(4); /* 2 4 6 8 */
root.right.left = getNode(6);
root.right.right = getNode(8);
int x = 10;
System.out.print("Count = " +
countPairs(root, x));
}
}
// This code is contributed by Rajput-Ji
C
// C# implementation to count pairs
// in a binary tree whose sum is
// equal to the given value x
using System;
class GFG
{
// structure of a node of a binary tree
class Node
{
public int data;
public Node left, right;
};
static Node head_ref;
// function to create and return a node
// of a binary tree
static Node getNode(int data)
{
// allocate space for the node
Node new_node = new Node();
// put in the data
new_node.data = data;
new_node.left = new_node.right = null;
return new_node;
}
// A simple recursive function to convert
// a given Binary tree to Doubly Linked List
// root -. Root of Binary Tree
// head_ref -. Pointer to head node of
// created doubly linked list
static void BToDLL(Node root)
{
// Base cases
if (root == null)
return;
// Recursively convert right subtree
BToDLL(root.right);
// insert root into DLL
root.right = head_ref;
// Change left pointer of previous head
if (head_ref != null)
head_ref.left = root;
// Change head of Doubly linked list
head_ref = root;
// Recursively convert left subtree
BToDLL(root.left);
}
// Split a doubly linked list (DLL)
// into 2 DLLs of half sizes
static Node split(Node head)
{
Node fast = head, slow = head;
while (fast.right != null &&
fast.right.right != null)
{
fast = fast.right.right;
slow = slow.right;
}
Node temp = slow.right;
slow.right = null;
return temp;
}
// Function to merge two sorted
// doubly linked lists
static Node merge(Node first,
Node second)
{
// If first linked list is empty
if (first == null)
return second;
// If second linked list is empty
if (second == null)
return first;
// Pick the smaller value
if (first.data < second.data)
{
first.right = merge(first.right,
second);
first.right.left = first;
first.left = null;
return first;
}
else
{
second.right = merge(first,
second.right);
second.right.left = second;
second.left = null;
return second;
}
}
// Function to do merge sort
static Node mergeSort(Node head)
{
if (head == null || head.right == null)
return head;
Node second = split(head);
// Recur for left and right halves
head = mergeSort(head);
second = mergeSort(second);
// Merge the two sorted halves
return merge(head, second);
}
// Function to count pairs in a sorted
// doubly linked list whose sum equal
// to given value x
static int pairSum(Node head, int x)
{
// Set two pointers, first to the beginning
// of DLL and second to the end of DLL.
Node first = head;
Node second = head;
while (second.right != null)
second = second.right;
int count = 0;
// The loop terminates when either of
// two pointers become null, or they
// cross each other (second.right == first),
// or they become same (first == second)
while (first != null && second != null &&
first != second && second.right != first)
{
// pair found
if ((first.data + second.data) == x)
{
count++;
// move first in forward direction
first = first.right;
// move second in backward direction
second = second.left;
}
else
{
if ((first.data + second.data) < x)
first = first.right;
else
second = second.left;
}
}
return count;
}
// function to count pairs in a binary tree
// whose sum is equal to given value x
static int countPairs(Node root, int x)
{
head_ref = null;
// Convert binary tree to
// doubly linked list
BToDLL(root);
// sort DLL
head_ref = mergeSort(head_ref);
// count pairs
return pairSum(head_ref, x);
}
// Driver Code
public static void Main(String[] args)
{
// formation of binary tree
Node root = getNode(5); /* 5 */
root.left = getNode(3); /* / \ */
root.right = getNode(7); /* 3 7 */
root.left.left = getNode(2); /* / \ / \ */
root.left.right = getNode(4); /* 2 4 6 8 */
root.right.left = getNode(6);
root.right.right = getNode(8);
int x = 10;
Console.Write("Count = " +
countPairs(root, x));
}
}
// This code is contributed by Rajput-Ji
输出:
Count = 3
时间复杂度:O(nLog n)
。
3)另一种有效的方法 – 无需转换为双链表和排序:
以下是步骤:
-
以任何顺序(前/后/中)遍历树。
-
创建一个空哈希,并继续在当前节点的值和
X
之间添加差异。 -
在每个节点上,检查其值是否在哈希中,如果是,则将计数增加 1,并且请勿在哈希中将该节点的值与
X
的差相加,以避免重复计算单个对。
# Python program to Count pairs
# in a binary tree whose sum is
# equal to a given value x
# Node class to represent a
# node in the binary tree
# with value, left and right attributes
class Node(object):
def __init__(self, value, left = None, right = None):
self.value = value
self.left = left
self.right = right
# To store count of pairs
count = 0
# To store difference between
# current node's value and x,
# acts a lookup for counting pairs
hash_t = set()
# The input, we need to count
# pairs whose sum is equal to x
x = 10
# Function to count number of pairs
# Does a pre-order traversal of the tree
def count_pairs_w_sum(root):
# global count
if root:
if root.value in hash_t:
count += 1
else:
hash_t.add(x-root.value)
count_pairs_w_sum(root.left)
count_pairs_w_sum(root.right)
# Entry point / Driver - Create a
# binary tree and call the function
# to get the count
if __name__ == '__main__':
root = Node(5)
root.left = Node(3)
root.right = Node(7)
root.left.left = Node(2)
root.left.right = Node(4)
root.right.left = Node(6)
root.right.right = Node(8)
count_pairs_w_sum(root)
print count
输出:
Count = 3
时间复杂度:O(n)
空间复杂度:O(n)
如果您喜欢 GeeksforGeeks 并希望做出贡献,则还可以使用 tribution.geeksforgeeks.org 撰写文章,或将您的文章邮寄至 tribution@geeksforgeeks.org。 查看您的文章出现在 GeeksforGeeks 主页上,并帮助其他 Geeks。
如果您发现任何不正确的地方,请单击下面的“改进文章”按钮,以改进本文。
版权属于:月萌API www.moonapi.com,转载请注明出处