📌  相关文章
📜  在BST中找到具有给定总和的所有对|套装2

📅  最后修改于: 2021-05-04 20:33:38             🧑  作者: Mango

给定二元搜索树和一个整数,任务是从树中查找所有和等于给定整数和的对
我们在这篇文章中讨论了类似的问题。

例子:

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 LeftListRightList中。到达叶节点后,从相应的ArrayList中取出左侧的最后一个值和右侧的最后一个值。将存在三个条件:

  1. 左侧值+右侧值删除LeftList的最后一个值,并使左侧执行到右侧,因为在树中从左侧移动到右侧时,节点的值会增加。
  2. 左侧值+右侧值>总和:删除RightList的最后一个值,并使右侧执行到左侧,因为在树中从右侧移动到左侧时,节点的值减小。
  3. 左侧值+右侧值=总和:删除两个列表的最后一个值,并使左侧执行在右侧,右侧执行在左侧。

下面是上述方法的实现:

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