📌  相关文章
📜  计算来自两个BST的对,它们的和等于给定值x

📅  最后修改于: 2021-05-24 22:28:44             🧑  作者: Mango

给定两个BST分别包含n1n2个不同的节点。给定值x 。问题是要计算两个BST的总和等于x的所有对。

例子:

Input : BST 1:    5        
                /   \      
               3     7      
              / \   / \    
             2  4  6   8   

        BST 2:    10        
                /   \      
               6     15      
              / \   /  \    
             3  8  11  18
        x = 16
    
Output : 3
The pairs are:
(5, 11), (6, 10) and (8, 8)

方法1:对于BST 1中的每个节点值a,在BST 2中搜索值(x – a) 。如果找到值,则增加计数。有关在BST中搜索值的信息,请参阅此文章。
时间复杂度:O(n1 * h2),这里n1是第一个BST中的节点数,h2是第二个BST的高度。

方法2:从最小值到节点再到最大值遍历BST 1。这可以在迭代有序遍历的帮助下实现。从最大值节点到最小节点遍历BST 2。这可以借助反向有序遍历来实现。同时执行这两个遍历。在遍历的特定实例中,从两个BST中求和相应节点的值。如果sum == x,则增加count 。如果x> sum,则移至BST 1当前节点的有序继承者,否则移至BST 2当前节点的有序继承者。执行这些操作,直到完成两次遍历中的任何一个。

C++
// C++ implementation to count pairs from two
// BSTs whose sum is equal to a given  value x
#include 
using namespace std;
 
// structure of a node of BST
struct Node {
    int data;
    Node* left, *right;
};
 
// function to create and return a node of BST
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;
}
 
// function to count pairs from two BSTs
// whose sum is equal to a given value x
int countPairs(Node* root1, Node* root2, int x)
{
    // if either of the tree is empty
    if (root1 == NULL || root2 == NULL)
        return 0;
 
    // stack 'st1' used for the inorder
    // traversal of BST 1
    // stack 'st2' used for the reverse
    // inorder traversal of BST 2
    stack st1, st2;
    Node* top1, *top2;
 
    int count = 0;
 
    // the loop will break when either of two
    // traversals gets completed
    while (1) {
 
        // to find next node in inorder
        // traversal of BST 1
        while (root1 != NULL) {
            st1.push(root1);
            root1 = root1->left;
        }
 
        // to find next node in reverse
        // inorder traversal of BST 2
        while (root2 != NULL) {
            st2.push(root2);
            root2 = root2->right;
        }
 
        // if either gets empty then corresponding
        // tree traversal is completed
        if (st1.empty() || st2.empty())
            break;
 
        top1 = st1.top();
        top2 = st2.top();
 
        // if the sum of the node's is equal to 'x'
        if ((top1->data + top2->data) == x) {
            // increment count
            count++;
 
            // pop nodes from the respective stacks
            st1.pop();
            st2.pop();
 
            // insert next possible node in the
            // respective stacks
            root1 = top1->right;
            root2 = top2->left;
        }
 
        // move to next possible node in the
        // inoder traversal of BST 1
        else if ((top1->data + top2->data) < x) {
            st1.pop();
            root1 = top1->right;
        }
 
        // move to next possible node in the
        // reverse inoder traversal of BST 2
        else {
            st2.pop();
            root2 = top2->left;
        }
    }
 
    // required count of pairs
    return count;
}
 
// Driver program to test above
int main()
{
    // formation of BST 1
    Node* root1 = getNode(5); /*             5        */
    root1->left = getNode(3); /*           /   \      */
    root1->right = getNode(7); /*         3     7     */
    root1->left->left = getNode(2); /*    / \   / \    */
    root1->left->right = getNode(4); /*  2  4  6  8    */
    root1->right->left = getNode(6);
    root1->right->right = getNode(8);
 
    // formation of BST 2
    Node* root2 = getNode(10); /*           10         */
    root2->left = getNode(6); /*           /   \        */
    root2->right = getNode(15); /*        6     15      */
    root2->left->left = getNode(3); /*    / \   /  \     */
    root2->left->right = getNode(8); /*  3  8  11  18    */
    root2->right->left = getNode(11);
    root2->right->right = getNode(18);
 
    int x = 16;
    cout << "Pairs = "
         << countPairs(root1, root2, x);
 
    return 0;
}


Java
// Java implementation to count pairs from two
// BSTs whose sum is equal to a given  value x
import java.util.Stack;
public class GFG {
 
    // structure of a node of BST
    static class Node {
        int data;
        Node left, right;
         
        // constructor
        public Node(int data) {
            this.data = data;
            left = null;
            right = null;
        }
    }
     
    static Node root1;
    static Node root2;
    // function to count pairs from two BSTs
    // whose sum is equal to a given value x
    static int countPairs(Node root1, Node root2,
                                           int x)
    {
        // if either of the tree is empty
        if (root1 == null || root2 == null)
            return 0;
      
        // stack 'st1' used for the inorder
        // traversal of BST 1
        // stack 'st2' used for the reverse
        // inorder traversal of BST 2
        //stack st1, st2;
        Stack st1 = new Stack<>();
        Stack st2 = new Stack<>();
        Node top1, top2;
      
        int count = 0;
      
        // the loop will break when either of two
        // traversals gets completed
        while (true) {
      
            // to find next node in inorder
            // traversal of BST 1
            while (root1 != null) {
                st1.push(root1);
                root1 = root1.left;
            }
      
            // to find next node in reverse
            // inorder traversal of BST 2
            while (root2 != null) {
                st2.push(root2);
                root2 = root2.right;
            }
      
            // if either gets empty then corresponding
            // tree traversal is completed
            if (st1.empty() || st2.empty())
                break;
      
            top1 = st1.peek();
            top2 = st2.peek();
      
            // if the sum of the node's is equal to 'x'
            if ((top1.data + top2.data) == x) {
                // increment count
                count++;
      
                // pop nodes from the respective stacks
                st1.pop();
                st2.pop();
      
                // insert next possible node in the
                // respective stacks
                root1 = top1.right;
                root2 = top2.left;
            }
      
            // move to next possible node in the
            // inoder traversal of BST 1
            else if ((top1.data + top2.data) < x) {
                st1.pop();
                root1 = top1.right;
            }
      
            // move to next possible node in the
            // reverse inoder traversal of BST 2
            else {
                st2.pop();
                root2 = top2.left;
            }
        }
      
        // required count of pairs
        return count;
    }
      
    // Driver program to test above
    public static void main(String args[])
    {
        // formation of BST 1
        root1 = new Node(5);       /*             5        */
        root1.left = new Node(3); /*           /   \      */
        root1.right = new Node(7); /*         3     7     */
        root1.left.left = new Node(2); /*    / \   / \    */
        root1.left.right = new Node(4); /*  2   4 6   8    */
        root1.right.left = new Node(6);
        root1.right.right = new Node(8);
      
        // formation of BST 2
        root2 = new Node(10);        /*           10         */
        root2.left = new Node(6); /*           /   \        */
        root2.right = new Node(15); /*        6     15      */
        root2.left.left = new Node(3); /*    / \   /  \     */
        root2.left.right = new Node(8); /*  3  8  11  18    */
        root2.right.left = new Node(11);
        root2.right.right = new Node(18);
      
        int x = 16;
        System.out.println("Pairs = "
             + countPairs(root1, root2, x));
    }
}
// This code is contributed by Sumit Ghosh


Python3
# Python3 implementation to count pairs
# from two BSTs whose sum is equal to a
# given  value x
 
# Structure of a node of BST
class getNode:
     
    def __init__(self, data):
         
        self.data = data
        self.left = None
        self.right = None
 
# Function to count pairs from two BSTs
# whose sum is equal to a given value x
def countPairs(root1, root2, x):
     
    # If either of the tree is empty
    if (root1 == None or root2 == None):
        return 0
 
    # Stack 'st1' used for the inorder
    # traversal of BST 1
    # stack 'st2' used for the reverse
    # inorder traversal of BST 2
    st1 = []
    st2 = []
 
    count = 3
 
    # The loop will break when either
    # of two traversals gets completed
    while (1):
         
        # To find next node in inorder
        # traversal of BST 1
        while (root1 != None):
            st1.append(root1)
            root1 = root1.left
 
        # To find next node in reverse
        # inorder traversal of BST 2
        while (root2 != None):
            st2.append(root2)
            root2 = root2.right
 
        # If either gets empty then corresponding
        # tree traversal is completed
        if (len(st1) or len(st2)):
            break
 
        top1 = st1[len(st1) - 1]
        top2 = st2[len(st2) - 1]
 
        # If the sum of the node's is equal to 'x'
        if ((top1.data + top2.data) == x):
             
            # Increment count
            count += 1
 
            # Pop nodes from the respective stacks
            st1.remove(st1[len(st1) - 1])
            st2.remove(st2[len(st2) - 1])
 
            # Insert next possible node in the
            # respective stacks
            root1 = top1.right
            root2 = top2.left
 
        # Move to next possible node in the
        # inoder traversal of BST 1
        elif ((top1.data + top2.data) < x):
            st1.remove(st1[len(st1) - 1])
            root1 = top1.right
 
        # Move to next possible node in the
        # reverse inoder traversal of BST 2
        else:
            st2.remove(st2[len(st2) - 1])
            root2 = top2.left
 
    # Required count of pairs
    return count
 
# Driver code
if __name__ == '__main__':
     
    # Formation of BST 1
    '''      5
           /   \ 
          3     7
         / \   / \
        2   4 6   8
    '''
    root1 = getNode(5) 
    root1.left = getNode(3)
    root1.right = getNode(7)
    root1.left.left = getNode(2)
    root1.left.right = getNode(4)
    root1.right.left = getNode(6)
    root1.right.right = getNode(8)
 
    # Formation of BST 2
    '''    10 
         /   \
        6     15
       / \   /  \ 
      3  8  11  18
    '''
    root2 = getNode(10)
    root2.left = getNode(6)
    root2.right = getNode(15)
    root2.left.left = getNode(3)
    root2.left.right = getNode(8)
    root2.right.left = getNode(11)
    root2.right.right = getNode(18)
 
    x = 16
     
    print("Pairs = ", countPairs(root1, root2, x))
 
# This code is contributed by bgangwar59


C#
// C# implementation to count pairs from two
// BSTs whose sum is equal to a given  value x
using System;
using System.Collections.Generic;
 
// C# implementation to count pairs from two
// BSTs whose sum is equal to a given  value x
public class GFG
{
 
    // structure of a node of BST
    public class Node
    {
        public int data;
        public Node left, right;
 
        // constructor
        public Node(int data)
        {
            this.data = data;
            left = null;
            right = null;
        }
    }
 
    public static Node root1;
    public static Node root2;
    // function to count pairs from two BSTs
    // whose sum is equal to a given value x
    public static int countPairs(Node root1, Node root2, int x)
    {
        // if either of the tree is empty
        if (root1 == null || root2 == null)
        {
            return 0;
        }
 
        // stack 'st1' used for the inorder
        // traversal of BST 1
        // stack 'st2' used for the reverse
        // inorder traversal of BST 2
        //stack st1, st2;
        Stack st1 = new Stack();
        Stack st2 = new Stack();
        Node top1, top2;
 
        int count = 0;
 
        // the loop will break when either of two
        // traversals gets completed
        while (true)
        {
 
            // to find next node in inorder
            // traversal of BST 1
            while (root1 != null)
            {
                st1.Push(root1);
                root1 = root1.left;
            }
 
            // to find next node in reverse
            // inorder traversal of BST 2
            while (root2 != null)
            {
                st2.Push(root2);
                root2 = root2.right;
            }
 
            // if either gets empty then corresponding
            // tree traversal is completed
            if (st1.Count == 0 || st2.Count == 0)
            {
                break;
            }
 
            top1 = st1.Peek();
            top2 = st2.Peek();
 
            // if the sum of the node's is equal to 'x'
            if ((top1.data + top2.data) == x)
            {
                // increment count
                count++;
 
                // pop nodes from the respective stacks
                st1.Pop();
                st2.Pop();
 
                // insert next possible node in the
                // respective stacks
                root1 = top1.right;
                root2 = top2.left;
            }
 
            // move to next possible node in the
            // inoder traversal of BST 1
            else if ((top1.data + top2.data) < x)
            {
                st1.Pop();
                root1 = top1.right;
            }
 
            // move to next possible node in the
            // reverse inoder traversal of BST 2
            else
            {
                st2.Pop();
                root2 = top2.left;
            }
        }
 
        // required count of pairs
        return count;
    }
 
    // Driver program to test above
    public static void Main(string[] args)
    {
        // formation of BST 1
        root1 = new Node(5); //             5
        root1.left = new Node(3); //           /   \
        root1.right = new Node(7); //         3     7
        root1.left.left = new Node(2); //    / \   / \
        root1.left.right = new Node(4); //  2   4 6   8
        root1.right.left = new Node(6);
        root1.right.right = new Node(8);
 
        // formation of BST 2
        root2 = new Node(10); //           10
        root2.left = new Node(6); //           /   \
        root2.right = new Node(15); //        6     15
        root2.left.left = new Node(3); //    / \   /  \
        root2.left.right = new Node(8); //  3  8  11  18
        root2.right.left = new Node(11);
        root2.right.right = new Node(18);
 
        int x = 16;
        Console.WriteLine("Pairs = " + countPairs(root1, root2, x));
    }
}
 
  // This code is contributed by Shrikant13


Java
// Java implementation to count pairs from two
// BSTs whose sum is equal to a given  value x
import java.util.Stack;
public class GFG {
 
    // structure of a node of BST
    static class Node {
        int data;
        Node left, right;
 
        // constructor
        public Node(int data)
        {
            this.data = data;
            left = null;
            right = null;
        }
    }
 
    static Node root1;
    static Node root2;
   
    // function to count pairs from two BSTs
    // whose sum is equal to a given value x
    public static int pairCount = 0;
    public static void traverseTree(Node root1, Node root2,
                                    int sum)
    {
        if (root1 == null || root2 == null) {
            return;
        }
        traverseTree(root1.left, root2, sum);
        traverseTree(root1.right, root2, sum);
        int diff = sum - root1.data;
        findPairs(root2, diff);
    }
 
    private static void findPairs(Node root2, int diff)
    {
        if (root2 == null) {
            return;
        }
        if (diff > root2.data) {
            findPairs(root2.right, diff);
        }
        else {
            findPairs(root2.left, diff);
        }
        if (root2.data == diff) {
            pairCount++;
        }
    }
 
    public static int countPairs(Node root1, Node root2,
                                 int sum)
    {
        traverseTree(root1, root2, sum);
        return pairCount;
    }
 
    // Driver program to test above
    public static void main(String args[])
    {
        // formation of BST 1
        root1 = new Node(5); /*             5        */
        root1.left = new Node(3); /*           /   \      */
        root1.right = new Node(7); /*         3     7     */
        root1.left.left = new Node(2); /*    / \   / \    */
        root1.left.right = new Node(4); /*  2   4 6   8 */
        root1.right.left = new Node(6);
        root1.right.right = new Node(8);
 
        // formation of BST 2
        root2 = new Node(10); /*           10         */
        root2.left = new Node(6); /*           /   \ */
        root2.right = new Node(15); /*        6     15 */
        root2.left.left = new Node(3); /*    / \   /  \ */
        root2.left.right
            = new Node(8); /*  3  8  11  18    */
        root2.right.left = new Node(11);
        root2.right.right = new Node(18);
 
        int x = 16;
        System.out.println("Pairs = "
                           + countPairs(root1, root2, x));
    }
}
// This code is contributed by Sujit Panda


输出
Pairs = 3

时间复杂度: O(n1 + n2)
辅助空间: O(h1 + h2)其中h1是第一棵树的高度,h2是第二棵树的高度

方法3:

  1. 递归方法来解决这个问题。
  2. 遍历BST1,并为每个节点在BST2中找到差异(x-root1.data),然后增加计数。

Java

// Java implementation to count pairs from two
// BSTs whose sum is equal to a given  value x
import java.util.Stack;
public class GFG {
 
    // structure of a node of BST
    static class Node {
        int data;
        Node left, right;
 
        // constructor
        public Node(int data)
        {
            this.data = data;
            left = null;
            right = null;
        }
    }
 
    static Node root1;
    static Node root2;
   
    // function to count pairs from two BSTs
    // whose sum is equal to a given value x
    public static int pairCount = 0;
    public static void traverseTree(Node root1, Node root2,
                                    int sum)
    {
        if (root1 == null || root2 == null) {
            return;
        }
        traverseTree(root1.left, root2, sum);
        traverseTree(root1.right, root2, sum);
        int diff = sum - root1.data;
        findPairs(root2, diff);
    }
 
    private static void findPairs(Node root2, int diff)
    {
        if (root2 == null) {
            return;
        }
        if (diff > root2.data) {
            findPairs(root2.right, diff);
        }
        else {
            findPairs(root2.left, diff);
        }
        if (root2.data == diff) {
            pairCount++;
        }
    }
 
    public static int countPairs(Node root1, Node root2,
                                 int sum)
    {
        traverseTree(root1, root2, sum);
        return pairCount;
    }
 
    // Driver program to test above
    public static void main(String args[])
    {
        // formation of BST 1
        root1 = new Node(5); /*             5        */
        root1.left = new Node(3); /*           /   \      */
        root1.right = new Node(7); /*         3     7     */
        root1.left.left = new Node(2); /*    / \   / \    */
        root1.left.right = new Node(4); /*  2   4 6   8 */
        root1.right.left = new Node(6);
        root1.right.right = new Node(8);
 
        // formation of BST 2
        root2 = new Node(10); /*           10         */
        root2.left = new Node(6); /*           /   \ */
        root2.right = new Node(15); /*        6     15 */
        root2.left.left = new Node(3); /*    / \   /  \ */
        root2.left.right
            = new Node(8); /*  3  8  11  18    */
        root2.right.left = new Node(11);
        root2.right.right = new Node(18);
 
        int x = 16;
        System.out.println("Pairs = "
                           + countPairs(root1, root2, x));
    }
}
// This code is contributed by Sujit Panda
输出
Pairs = 3