Sum of two nodes in binary search tree (Sword finger offer-56)

Original question link

Title Description

Given the root node root of a binary search tree and an integer k, please judge whether there are two nodes in the binary search tree, and the sum of their values is equal to K. It is assumed that the values of nodes in the binary search tree are unique.

Example 1

Input: root = [8,6,10,5,7,9,11], k = 12
Output: true
Explanation: the sum of node 5 and node 7 is equal to 12

Example 2

Input: root = [8,6,10,5,7,9,11], k = 22
Output: false
Explanation: there is no node whose sum of two node values is 22

Train of thought 1

Stack + hash table. The hash table stores the values of the traversed nodes. For each node cur traversed, judge whether k-cur.val exists in the hash table. If it exists, return true directly. Otherwise, store cur.val in the hash table. If true is not returned after traversing all nodes, it means that there are no two nodes whose sum is equal to K, and false is returned

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean findTarget(TreeNode root, int k) {
        Stack<TreeNode> st = new Stack();
        Map<Integer, Integer> map = new HashMap();
        TreeNode cur = root;
        while(cur != null || !st.empty()){
            while(cur != null){
                st.push(cur);
                cur = cur.left;
            }
            cur = st.pop();
            if(map.containsKey(k - cur.val)){
                return true;
            }
            map.put(cur.val, 1);
            cur = cur.right;
        }
        return false;
    }
}

Train of thought 2

Since finding the sum of two numbers of binary search tree nodes, we can think of the sum of two numbers in the first question of LeetCode.

Original question link

To find the sum of two numbers in the array (ordered array), we use double pointers. The pointer left points to the smallest number and the pointer right points to the largest number. If left + right == k, it returns true; If left + right < K, left points to a larger number; If left + right > k, right points to a smaller number.
If true is not returned when left and right meet, it indicates that there is no number whose sum is equal to k, and false is returned.

Similarly, we can still use this method in binary search tree (the middle order traversal of binary search tree is also orderly). The only difference is that one traverses an array and the other traverses a tree.

We can still set two pointers. The left pointer points to the smallest node (the lowest left corner) in the binary search tree and the right pointer points to the largest node (the lowest right corner) in the binary search tree.
We can write an iterator class that traverses the tree. There are two methods in the iterator. One is to obtain the next node of the left pointer, that is, the smallest node larger than the current left pointer; The next node that obtains the right pointer, that is, the largest node smaller than the current right pointer.

Let's start with the code. The details are described below.

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean findTarget(TreeNode root, int k) {
        BSTIterator interator = new BSTIterator(root);
        int left = interator.getLeftNext();
        int right = interator.getRightNext();
        while(left < right){
            if(left + right == k){
                return true;
            }else if(left + right < k){
                left = interator.getLeftNext();
            }else{
                right = interator.getRightNext();
            }
        }
        return false;
    }

    private class BSTIterator {
        Stack<TreeNode> lst, rst;
        TreeNode lcur, rcur;

        public BSTIterator(TreeNode root) {
            lst = new Stack();
            rst = new Stack();
            lcur = root;
            rcur = root;
        }

		//Medium order traversal
        public int getLeftNext(){
            while(lcur != null){
                lst.push(lcur);
                lcur = lcur.left;
            }
            lcur = lst.pop();
            int val = lcur.val;
            lcur = lcur.right;
            return val;
        }
        
        //Inverse middle order traversal
        public int getRightNext(){   
            while(rcur != null){
                rst.push(rcur);
                rcur = rcur.right;
            }
            rcur = rst.pop();
            int val = rcur.val;
            rcur = rcur.left;
            return val;
        }   
    
    }
}

This iterator class is modified on the basis of medium order traversal

//Medium order traversal
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList();
        Stack<TreeNode> st = new Stack();
        TreeNode cur = root;
        while(cur != null || !st.empty()){
            while(cur != null){
                st.push(cur);
                cur = cur.left;
            }
            cur = st.pop();
            list.add(cur.val);
            cur = cur.right;
        }
        return list;
    }

}

Because we need to traverse from both ends, we can use two stacks and two pointers to reverse the middle order traversal operation and the middle order traversal operation.

Tags: Java Algorithm leetcode

Posted on Sun, 26 Sep 2021 20:28:54 -0400 by powaz