给定二元搜索树和一个整数和,任务是从树中查找所有和等于给定整数和的对。
我们在这篇文章中讨论了类似的问题。
例子:
Input:
2
/ \
1 6
/ \
5 7
/
3
\
4
sum = 8
Output:
1 7
2 6
3 5
Input:
2
/ \
1 3
\
4
sum = 5
Output:
1 4
2 3
方法:从左侧,左侧和右侧以预定顺序遍历树,并将左侧和右侧的值分别存储到ArrayList LeftList和RightList中。到达叶节点后,从相应的ArrayList中取出左侧的最后一个值和右侧的最后一个值。将存在三个条件:
- 左侧值+右侧值
删除LeftList的最后一个值,并使左侧执行到右侧,因为在树中从左侧移动到右侧时,节点的值会增加。 - 左侧值+右侧值>总和:删除RightList的最后一个值,并使右侧执行到左侧,因为在树中从右侧移动到左侧时,节点的值减小。
- 左侧值+右侧值=总和:删除两个列表的最后一个值,并使左侧执行在右侧,右侧执行在左侧。
下面是上述方法的实现:
C++
// C++ implementation of the
// above approach
#include
using namespace std;
struct Node
{
int data;
Node *left, *right,
*root;
Node(int data)
{
this -> data = data;
left = NULL;
right = NULL;
root = NULL;
}
};
// Function to add a node
// to the BST
Node* AddNode(Node *root,
int data)
{
// If the tree is empty,
// return a new node
if (root == NULL)
{
root = new Node(data);
return root;
}
// Otherwise, recur down
// the tree
if (root -> data < data)
root -> right = AddNode(root -> right,
data);
else if (root -> data > data)
root -> left = AddNode(root -> left,
data);
return root;
}
// Function to find the
// target pairs
void TargetPair(Node *node,
int tar)
{
// LeftList which stores
// the left side values
vector LeftList;
// RightList which stores
// the right side values
vector RightList;
// curr_left pointer is used
// for left side execution and
// curr_right pointer is used
// for right side execution
Node *curr_left = node;
Node *curr_right = node;
while (curr_left != NULL ||
curr_right != NULL ||
LeftList.size() > 0 &&
RightList.size() > 0)
{
// Storing the left side
// values into LeftList
// till leaf node not found
while (curr_left != NULL)
{
LeftList.push_back(curr_left);
curr_left = curr_left -> left;
}
// Storing the right side
// values into RightList
// till leaf node not found
while (curr_right != NULL)
{
RightList.push_back(curr_right);
curr_right = curr_right -> right;
}
// Last node of LeftList
Node *LeftNode =
LeftList[LeftList.size() - 1];
// Last node of RightList
Node *RightNode =
RightList[RightList.size() - 1];
int leftVal = LeftNode -> data;
int rightVal = RightNode -> data;
// To prevent repetition
// like 2, 6 and 6, 2
if (leftVal >= rightVal)
break;
// Delete the last value of LeftList
// and make the execution to the
// right side
if (leftVal + rightVal < tar)
{
LeftList.pop_back();
curr_left = LeftNode -> right;
}
// Delete the last value of RightList
// and make the execution to the left
// side
else if (leftVal + rightVal > tar)
{
RightList.pop_back();
curr_right = RightNode -> left;
}
// (left value + right value) = target
// then print the left value and right value
// Delete the last value of left and right list
// and make the left execution to right side
// and right side execution to left side
else
{
cout << LeftNode -> data << " " <<
RightNode -> data << endl;
RightList.pop_back();
LeftList.pop_back();
curr_left = LeftNode -> right;
curr_right = RightNode -> left;
}
}
}
// Driver code
int main()
{
Node *root = NULL;
root = AddNode(root, 2);
root = AddNode(root, 6);
root = AddNode(root, 5);
root = AddNode(root, 3);
root = AddNode(root, 4);
root = AddNode(root, 1);
root = AddNode(root, 7);
int sum = 8;
TargetPair(root, sum);
}
// This code is contributed by Rutvik_56
Java
// Java implementation of the approach
import java.util.*;
public class GFG {
// A binary tree node
public static class Node {
int data;
Node left, right, root;
Node(int data)
{
this.data = data;
}
}
// Function to add a node to the BST
public static Node AddNode(Node root, int data)
{
// If the tree is empty, return a new node
if (root == null) {
root = new Node(data);
return root;
}
// Otherwise, recur down the tree
if (root.data < data)
root.right = AddNode(root.right, data);
else if (root.data > data)
root.left = AddNode(root.left, data);
return root;
}
// Function to find the target pairs
public static void TargetPair(Node node, int tar)
{
// LeftList which stores the left side values
ArrayList LeftList = new ArrayList<>();
// RightList which stores the right side values
ArrayList RightList = new ArrayList<>();
// curr_left pointer is used for left side execution and
// curr_right pointer is used for right side execution
Node curr_left = node;
Node curr_right = node;
while (curr_left != null || curr_right != null
|| LeftList.size() > 0 && RightList.size() > 0) {
// Storing the left side values into LeftList
// till leaf node not found
while (curr_left != null) {
LeftList.add(curr_left);
curr_left = curr_left.left;
}
// Storing the right side values into RightList
// till leaf node not found
while (curr_right != null) {
RightList.add(curr_right);
curr_right = curr_right.right;
}
// Last node of LeftList
Node LeftNode = LeftList.get(LeftList.size() - 1);
// Last node of RightList
Node RightNode = RightList.get(RightList.size() - 1);
int leftVal = LeftNode.data;
int rightVal = RightNode.data;
// To prevent repetition like 2, 6 and 6, 2
if (leftVal >= rightVal)
break;
// Delete the last value of LeftList and make
// the execution to the right side
if (leftVal + rightVal < tar) {
LeftList.remove(LeftList.size() - 1);
curr_left = LeftNode.right;
}
// Delete the last value of RightList and make
// the execution to the left side
else if (leftVal + rightVal > tar) {
RightList.remove(RightList.size() - 1);
curr_right = RightNode.left;
}
// (left value + right value) = target
// then print the left value and right value
// Delete the last value of left and right list
// and make the left execution to right side
// and right side execution to left side
else {
System.out.println(LeftNode.data + " " + RightNode.data);
RightList.remove(RightList.size() - 1);
LeftList.remove(LeftList.size() - 1);
curr_left = LeftNode.right;
curr_right = RightNode.left;
}
}
}
// Driver code
public static void main(String[] b)
{
Node root = null;
root = AddNode(root, 2);
root = AddNode(root, 6);
root = AddNode(root, 5);
root = AddNode(root, 3);
root = AddNode(root, 4);
root = AddNode(root, 1);
root = AddNode(root, 7);
int sum = 8;
TargetPair(root, sum);
}
}
Python3
# Python3 implementation of the approach
# A binary tree node
class Node:
def __init__(self, key):
self.data = key
self.left = None
self.right = None
# Function to append a node to the BST
def AddNode(root, data):
# If the tree is empty, return a new node
if (root == None):
root = Node(data)
return root
# Otherwise, recur down the tree
if (root.data < data):
root.right = AddNode(root.right, data)
elif (root.data > data):
root.left = AddNode(root.left, data)
return root
# Function to find the target pairs
def TargetPair(node, tar):
# LeftList which stores the left side values
LeftList = []
# RightList which stores the right side values
RightList = []
# curr_left pointer is used for left
# side execution and curr_right pointer
# is used for right side execution
curr_left = node
curr_right = node
while (curr_left != None or
curr_right != None or
len(LeftList) > 0 and
len(RightList) > 0):
# Storing the left side values into
# LeftList till leaf node not found
while (curr_left != None):
LeftList.append(curr_left)
curr_left = curr_left.left
# Storing the right side values into
# RightList till leaf node not found
while (curr_right != None):
RightList.append(curr_right)
curr_right = curr_right.right
# Last node of LeftList
LeftNode = LeftList[-1]
# Last node of RightList
RightNode = RightList[-1]
leftVal = LeftNode.data
rightVal = RightNode.data
# To prevent repetition like 2, 6 and 6, 2
if (leftVal >= rightVal):
break
# Delete the last value of LeftList and
# make the execution to the right side
if (leftVal + rightVal < tar):
del LeftList[-1]
curr_left = LeftNode.right
# Delete the last value of RightList and
# make the execution to the left side
elif (leftVal + rightVal > tar):
del RightList[-1]
curr_right = RightNode.left
# (left value + right value) = target
# then print the left value and right value
# Delete the last value of left and right list
# and make the left execution to right side
# and right side execution to left side
else:
print(LeftNode.data, RightNode.data)
del RightList[-1]
del LeftList[-1]
curr_left = LeftNode.right
curr_right = RightNode.left
# Driver code
if __name__ == '__main__':
root = None
root = AddNode(root, 2)
root = AddNode(root, 6)
root = AddNode(root, 5)
root = AddNode(root, 3)
root = AddNode(root, 4)
root = AddNode(root, 1)
root = AddNode(root, 7)
sum = 8
TargetPair(root, sum)
# This code is contributed by mohit kumar 29
C#
// C# program to implement
// the above approach
using System.Collections.Generic;
using System;
class GFG
{
// A binary tree node
public class Node
{
public int data;
public Node left, right, root;
public Node(int data)
{
this.data = data;
}
}
// Function to add a node to the BST
public static Node AddNode(Node root, int data)
{
// If the tree is empty, return a new node
if (root == null)
{
root = new Node(data);
return root;
}
// Otherwise, recur down the tree
if (root.data < data)
root.right = AddNode(root.right, data);
else if (root.data > data)
root.left = AddNode(root.left, data);
return root;
}
// Function to find the target pairs
public static void TargetPair(Node node, int tar)
{
// LeftList which stores the left side values
List LeftList = new List();
// RightList which stores the right side values
List RightList = new List();
// curr_left pointer is used for left side execution and
// curr_right pointer is used for right side execution
Node curr_left = node;
Node curr_right = node;
while (curr_left != null || curr_right != null
|| LeftList.Count > 0 && RightList.Count > 0)
{
// Storing the left side values into LeftList
// till leaf node not found
while (curr_left != null)
{
LeftList.Add(curr_left);
curr_left = curr_left.left;
}
// Storing the right side values into RightList
// till leaf node not found
while (curr_right != null)
{
RightList.Add(curr_right);
curr_right = curr_right.right;
}
// Last node of LeftList
Node LeftNode = LeftList[LeftList.Count - 1];
// Last node of RightList
Node RightNode = RightList[RightList.Count - 1];
int leftVal = LeftNode.data;
int rightVal = RightNode.data;
// To prevent repetition like 2, 6 and 6, 2
if (leftVal >= rightVal)
break;
// Delete the last value of LeftList and make
// the execution to the right side
if (leftVal + rightVal < tar)
{
LeftList.RemoveAt(LeftList.Count - 1);
curr_left = LeftNode.right;
}
// Delete the last value of RightList and make
// the execution to the left side
else if (leftVal + rightVal > tar)
{
RightList.RemoveAt(RightList.Count - 1);
curr_right = RightNode.left;
}
// (left value + right value) = target
// then print the left value and right value
// Delete the last value of left and right list
// and make the left execution to right side
// and right side execution to left side
else
{
Console.WriteLine(LeftNode.data + " " + RightNode.data);
RightList.RemoveAt(RightList.Count - 1);
LeftList.RemoveAt(LeftList.Count - 1);
curr_left = LeftNode.right;
curr_right = RightNode.left;
}
}
}
// Driver code
public static void Main(String[] b)
{
Node root = null;
root = AddNode(root, 2);
root = AddNode(root, 6);
root = AddNode(root, 5);
root = AddNode(root, 3);
root = AddNode(root, 4);
root = AddNode(root, 1);
root = AddNode(root, 7);
int sum = 8;
TargetPair(root, sum);
}
}
/* This code contributed by PrinciRaj1992 */
输出:
1 7
2 6
3 5