给定两个二进制搜索树(BST)和给定的总和。任务是找到具有给定总和的对,以便每个对元素必须位于不同的BST中。
例子:
Input : sum = 10
8 5
/ \ / \
3 10 2 18
/ \ \ / \
1 6 14 1 3
/ \ / \
5 7 13 4
Output : (5,5), (6,4), (7,3), (8,2)
In above pairs first element lies in first
BST and second element lies in second BST
解决此问题的简单方法是将一棵树的顺序遍历存储在辅助数组中,然后从数组中一个接一个地挑选元素,并在给定总和的另一棵树中找到它的对。如果两个树中的节点总数相等,则此方法的时间复杂度将为O(n 2 )。
此解决方案的有效解决方案是将两个BST的有序遍历存储在两个不同的辅助数组vect1 []和vect2 []中。现在,我们遵循本文的method1 。由于BST的有序遍历总是给出排序的序列,因此我们不需要对数组进行排序。
- 将迭代器向左移,并将其指向左角vect1 []。
- 将迭代器右移,并将其指向右角vect2 []。
- 现在,如果vect11 [left] + vect2 [right]
则将vite1 []中的左迭代器向前移动,即;左++ 。 - 现在,如果vect1 [left] + vect2 [right]> sum,则在vect []中向右移动迭代器,即:对– 。
以下是上述想法的实现。
C++
// C++ program to find pairs with given sum such
// that one element of pair exists in one BST and
// other in other BST.
#include
using namespace std;
// A binary Tree node
struct Node
{
int data;
struct Node *left, *right;
};
// A utility function to create a new BST node
// with key as given num
struct Node* newNode(int num)
{
struct Node* temp = new Node;
temp->data = num;
temp->left = temp->right = NULL;
return temp;
}
// A utility function to insert a given key to BST
Node* insert(Node* root, int key)
{
if (root == NULL)
return newNode(key);
if (root->data > key)
root->left = insert(root->left, key);
else
root->right = insert(root->right, key);
return root;
}
// store storeInorder traversal in auxiliary array
void storeInorder(Node *ptr, vector &vect)
{
if (ptr==NULL)
return;
storeInorder(ptr->left, vect);
vect.push_back(ptr->data);
storeInorder(ptr->right, vect);
}
// Function to find pair for given sum in different bst
// vect1[] --> stores storeInorder traversal of first bst
// vect2[] --> stores storeInorder traversal of second bst
void pairSumUtil(vector &vect1, vector &vect2,
int sum)
{
// Initialize two indexes to two different corners
// of two vectors.
int left = 0;
int right = vect2.size() - 1;
// find pair by moving two corners.
while (left < vect1.size() && right >= 0)
{
// If we found a pair
if (vect1[left] + vect2[right] == sum)
{
cout << "(" << vect1[left] << ", "
<< vect2[right] << "), ";
left++;
right--;
}
// If sum is more, move to higher value in
// first vector.
else if (vect1[left] + vect2[right] < sum)
left++;
// If sum is less, move to lower value in
// second vector.
else
right--;
}
}
// Prints all pairs with given "sum" such that one
// element of pair is in tree with root1 and other
// node is in tree with root2.
void pairSum(Node *root1, Node *root2, int sum)
{
// Store inorder traversals of two BSTs in two
// vectors.
vector vect1, vect2;
storeInorder(root1, vect1);
storeInorder(root2, vect2);
// Now the problem reduces to finding a pair
// with given sum such that one element is in
// vect1 and other is in vect2.
pairSumUtil(vect1, vect2, sum);
}
// Driver program to run the case
int main()
{
// first BST
struct Node* root1 = NULL;
root1 = insert(root1, 8);
root1 = insert(root1, 10);
root1 = insert(root1, 3);
root1 = insert(root1, 6);
root1 = insert(root1, 1);
root1 = insert(root1, 5);
root1 = insert(root1, 7);
root1 = insert(root1, 14);
root1 = insert(root1, 13);
// second BST
struct Node* root2 = NULL;
root2 = insert(root2, 5);
root2 = insert(root2, 18);
root2 = insert(root2, 2);
root2 = insert(root2, 1);
root2 = insert(root2, 3);
root2 = insert(root2, 4);
int sum = 10;
pairSum(root1, root2, sum);
return 0;
}
Java
// Java program to find pairs with given sum such
// that one element of pair exists in one BST and
// other in other BST.
import java.util.*;
class solution
{
// A binary Tree node
static class Node
{
int data;
Node left, right;
};
// A utility function to create a new BST node
// with key as given num
static Node newNode(int num)
{
Node temp = new Node();
temp.data = num;
temp.left = temp.right = null;
return temp;
}
// A utility function to insert a given key to BST
static Node insert(Node root, int key)
{
if (root == null)
return newNode(key);
if (root.data > key)
root.left = insert(root.left, key);
else
root.right = insert(root.right, key);
return root;
}
// store storeInorder traversal in auxiliary array
static void storeInorder(Node ptr, Vector vect)
{
if (ptr==null)
return;
storeInorder(ptr.left, vect);
vect.add(ptr.data);
storeInorder(ptr.right, vect);
}
// Function to find pair for given sum in different bst
// vect1.get() -. stores storeInorder traversal of first bst
// vect2.get() -. stores storeInorder traversal of second bst
static void pairSumUtil(Vector vect1, Vector vect2,
int sum)
{
// Initialize two indexes to two different corners
// of two Vectors.
int left = 0;
int right = vect2.size() - 1;
// find pair by moving two corners.
while (left < vect1.size() && right >= 0)
{
// If we found a pair
if (vect1.get(left) + vect2.get(right) == sum)
{
System.out.print( "(" +vect1.get(left) + ", "+ vect2.get(right) + "), ");
left++;
right--;
}
// If sum is more, move to higher value in
// first Vector.
else if (vect1.get(left) + vect2.get(right) < sum)
left++;
// If sum is less, move to lower value in
// second Vector.
else
right--;
}
}
// Prints all pairs with given "sum" such that one
// element of pair is in tree with root1 and other
// node is in tree with root2.
static void pairSum(Node root1, Node root2, int sum)
{
// Store inorder traversals of two BSTs in two
// Vectors.
Vector vect1= new Vector(), vect2= new Vector();
storeInorder(root1, vect1);
storeInorder(root2, vect2);
// Now the problem reduces to finding a pair
// with given sum such that one element is in
// vect1 and other is in vect2.
pairSumUtil(vect1, vect2, sum);
}
// Driver program to run the case
public static void main(String args[])
{
// first BST
Node root1 = null;
root1 = insert(root1, 8);
root1 = insert(root1, 10);
root1 = insert(root1, 3);
root1 = insert(root1, 6);
root1 = insert(root1, 1);
root1 = insert(root1, 5);
root1 = insert(root1, 7);
root1 = insert(root1, 14);
root1 = insert(root1, 13);
// second BST
Node root2 = null;
root2 = insert(root2, 5);
root2 = insert(root2, 18);
root2 = insert(root2, 2);
root2 = insert(root2, 1);
root2 = insert(root2, 3);
root2 = insert(root2, 4);
int sum = 10;
pairSum(root1, root2, sum);
}
}
//contributed by Arnab Kundu
Python3
# Python3 program to find pairs with given
# sum such that one element of pair exists
# in one BST and other in other BST.
# A utility function to create a new
# BST node with key as given num
class newNode:
# Constructor to create a new node
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# A utility function to insert a
# given key to BST
def insert(root, key):
if root == None:
return newNode(key)
if root.data > key:
root.left = insert(root.left, key)
else:
root.right = insert(root.right, key)
return root
# store storeInorder traversal in
# auxiliary array
def storeInorder(ptr, vect):
if ptr == None:
return
storeInorder(ptr.left, vect)
vect.append(ptr.data)
storeInorder(ptr.right, vect)
# Function to find pair for given
# sum in different bst
# vect1[] --> stores storeInorder traversal
# of first bst
# vect2[] --> stores storeInorder traversal
# of second bst
def pairSumUtil(vect1, vect2, Sum):
# Initialize two indexes to two
# different corners of two lists.
left = 0
right = len(vect2) - 1
# find pair by moving two corners.
while left < len(vect1) and right >= 0:
# If we found a pair
if vect1[left] + vect2[right] == Sum:
print("(", vect1[left], ",",
vect2[right], "),", end = " ")
left += 1
right -= 1
# If sum is more, move to higher
# value in first lists.
elif vect1[left] + vect2[right] < Sum:
left += 1
# If sum is less, move to lower
# value in second lists.
else:
right -= 1
# Prints all pairs with given "sum" such that one
# element of pair is in tree with root1 and other
# node is in tree with root2.
def pairSum(root1, root2, Sum):
# Store inorder traversals of
# two BSTs in two lists.
vect1 = []
vect2 = []
storeInorder(root1, vect1)
storeInorder(root2, vect2)
# Now the problem reduces to finding a
# pair with given sum such that one
# element is in vect1 and other is in vect2.
pairSumUtil(vect1, vect2, Sum)
# Driver Code
if __name__ == '__main__':
# first BST
root1 = None
root1 = insert(root1, 8)
root1 = insert(root1, 10)
root1 = insert(root1, 3)
root1 = insert(root1, 6)
root1 = insert(root1, 1)
root1 = insert(root1, 5)
root1 = insert(root1, 7)
root1 = insert(root1, 14)
root1 = insert(root1, 13)
# second BST
root2 = None
root2 = insert(root2, 5)
root2 = insert(root2, 18)
root2 = insert(root2, 2)
root2 = insert(root2, 1)
root2 = insert(root2, 3)
root2 = insert(root2, 4)
Sum = 10
pairSum(root1, root2, Sum)
# This code is contributed by PranchalK
C#
using System;
using System.Collections.Generic;
// C# program to find pairs with given sum such
// that one element of pair exists in one BST and
// other in other BST.
public class solution
{
// A binary Tree node
public class Node
{
public int data;
public Node left, right;
}
// A utility function to create a new BST node
// with key as given num
public static Node newNode(int num)
{
Node temp = new Node();
temp.data = num;
temp.left = temp.right = null;
return temp;
}
// A utility function to insert a given key to BST
public static Node insert(Node root, int key)
{
if (root == null)
{
return newNode(key);
}
if (root.data > key)
{
root.left = insert(root.left, key);
}
else
{
root.right = insert(root.right, key);
}
return root;
}
// store storeInorder traversal in auxiliary array
public static void storeInorder(Node ptr, List vect)
{
if (ptr == null)
{
return;
}
storeInorder(ptr.left, vect);
vect.Add(ptr.data);
storeInorder(ptr.right, vect);
}
// Function to find pair for given sum in different bst
// vect1.get() -. stores storeInorder traversal of first bst
// vect2.get() -. stores storeInorder traversal of second bst
public static void pairSumUtil(List vect1, List vect2, int sum)
{
// Initialize two indexes to two different corners
// of two Vectors.
int left = 0;
int right = vect2.Count - 1;
// find pair by moving two corners.
while (left < vect1.Count && right >= 0)
{
// If we found a pair
if (vect1[left] + vect2[right] == sum)
{
Console.Write("(" + vect1[left] + ", " + vect2[right] + "), ");
left++;
right--;
}
// If sum is more, move to higher value in
// first Vector.
else if (vect1[left] + vect2[right] < sum)
{
left++;
}
// If sum is less, move to lower value in
// second Vector.
else
{
right--;
}
}
}
// Prints all pairs with given "sum" such that one
// element of pair is in tree with root1 and other
// node is in tree with root2.
public static void pairSum(Node root1, Node root2, int sum)
{
// Store inorder traversals of two BSTs in two
// Vectors.
List vect1 = new List(), vect2 = new List();
storeInorder(root1, vect1);
storeInorder(root2, vect2);
// Now the problem reduces to finding a pair
// with given sum such that one element is in
// vect1 and other is in vect2.
pairSumUtil(vect1, vect2, sum);
}
// Driver program to run the case
public static void Main(string[] args)
{
// first BST
Node root1 = null;
root1 = insert(root1, 8);
root1 = insert(root1, 10);
root1 = insert(root1, 3);
root1 = insert(root1, 6);
root1 = insert(root1, 1);
root1 = insert(root1, 5);
root1 = insert(root1, 7);
root1 = insert(root1, 14);
root1 = insert(root1, 13);
// second BST
Node root2 = null;
root2 = insert(root2, 5);
root2 = insert(root2, 18);
root2 = insert(root2, 2);
root2 = insert(root2, 1);
root2 = insert(root2, 3);
root2 = insert(root2, 4);
int sum = 10;
pairSum(root1, root2, sum);
}
}
// This code is contributed by Shrikant13
输出:
(5,5),(6,4),(7,3),(8,2)
时间复杂度: O(n)
辅助空间: O(n)
我们还有另一种空间优化的方法来解决此问题。这个想法是将bst转换为双向链表,并将上述方法应用于双向链表。请参阅本文。
时间复杂度: O(n)
辅助空间: O(1)