Two Sum IV - Input is a BST LT653

Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that their sum is equal to the given target.

Example 1:

Input: 
    5
   / \
  3   6
 / \   \
2   4   7

Target = 9

Output: True

 

Example 2:

Input: 
    5
   / \
  3   6
 / \   \
2   4   7

Target = 28

Output: False

Idea 1. Similar to Two Sum LT1, use set to record the element while looping the BST and check if target - num exists.

Time complexity: O(n)

Space complexity: O(h) + O(n)

 1 /**
 2  * Definition for a binary tree node.
 3  * public class TreeNode {
 4  *     int val;
 5  *     TreeNode left;
 6  *     TreeNode right;
 7  *     TreeNode(int x) { val = x; }
 8  * }
 9  */
10 class Solution {
11     private boolean findHelper(TreeNode root, int k, Set<Integer> record) {
12         if(root == null) {
13             return false;
14         }
15         
16         if(record.contains(k - root.val)) {
17             return true;
18         }
19         record.add(root.val);
20         return findHelper(root.left, k, record)
21             || findHelper(root.right, k, record);
22     }
23     public boolean findTarget(TreeNode root, int k) {
24         return findHelper(root, k, new HashSet<Integer>());
25     }
26 }

Idea 2 BFS + Set, insted of DFS(preorder, inorder, postordal) traversal like idea 1

Time complexity: O(n)

Space complexity: O(n)

 1 class Solution {
 2     public boolean findTarget(TreeNode root, int k) {
 3         if(root == null) {
 4             return false;
 5         }
 6         Deque<TreeNode> queue = new ArrayDeque<>();
 7         Set<Integer> record = new HashSet<>();
 8         queue.add(root);
 9         
10         
11         while(!queue.isEmpty()) {
12             TreeNode node = queue.pollFirst();
13             if(record.contains(k - node.val)) {
14                     return true;
15             }
16             record.add(node.val);
17             if(node.left != null) {
18                 queue.offerLast(node.left);
19             }
20             if(node.right != null) {
21                 queue.offerLast(node.right);
22             }
23         }
24         
25         return false;
26     }
27 }

Idea 3. Store the ordered nums in array after inorder traversal, then two pointer scannning towards each other.

Time complexity: O(n)

Space complexity: O(h) + O(n)

 1 /**
 2  * Definition for a binary tree node.
 3  * public class TreeNode {
 4  *     int val;
 5  *     TreeNode left;
 6  *     TreeNode right;
 7  *     TreeNode(int x) { val = x; }
 8  * }
 9  */
10 class Solution {
11     private void inorderWalk(TreeNode root, List<Integer> nums) {
12         if(root == null) {
13             return;
14         }
15         
16         inorderWalk(root.left, nums);
17         nums.add(root.val);
18         inorderWalk(root.right, nums);
19     }
20     
21     public boolean findTarget(TreeNode root, int k) {
22         List<Integer> nums = new ArrayList<>();
23         
24         inorderWalk(root, nums);
25         
26         for(int left = 0, right = nums.size()-1; left < right; ) {
27             int sum = nums.get(left) + nums.get(right);
28             if(sum == k) {
29                 return true;
30             }
31             else if(sum < k) {
32                 ++left;
33             }
34             else {
35                 --right;
36             }
37         }
38         
39         return false;
40     }
41 }

Idea 4. Inorder walk iterator  + reversed inorder walk iterator to avoid extra space.

巧点: 1. 怎么停止循环?利用bst有序不重复,left < right; 否则 iter.hasNext()

          2. 只有需要时才移动iterator

          3. next() -> 遍历到下一个数就返回

Time complexity: O(n)

Space complexity: O(h)

 1 import java.util.NoSuchElementException;
 2 import java.lang.UnsupportedOperationException;
 3 /**
 4  * Definition for a binary tree node.
 5  * public class TreeNode {
 6  *     int val;
 7  *     TreeNode left;
 8  *     TreeNode right;
 9  *     TreeNode(int x) { val = x; }
10  * }
11  */
12 
13 class InorderIterator implements Iterator<TreeNode> {
14     private TreeNode curr;
15     private Deque<TreeNode> stack;
16     private boolean forward;
17     
18     public InorderIterator(TreeNode root, boolean forward) {
19         this.curr = root;
20         this.stack = new ArrayDeque<>();
21         this.forward = forward;
22     }
23     
24     public boolean hasNext() {
25         return curr!= null || !stack.isEmpty();
26     }
27     
28     public TreeNode next() {
29         if(!hasNext()) {
30             throw new NoSuchElementException("tree run out of elements");
31         }
32         while(curr != null) {
33             stack.push(curr);
34             if(forward) {
35                 curr = curr.left;
36             }
37             else {
38                 curr = curr.right;
39             }
40         }
41         curr = stack.pop();
42         TreeNode prev = curr;
43         if(forward) {
44             curr = curr.right;
45         }
46         else {
47             curr = curr.left;
48         }
49         return prev;
50     }
51     
52     public void remove() {
53         throw new UnsupportedOperationException();
54     }
55 }
56 
57 class Solution {
58     public boolean findTarget(TreeNode root, int k) {
59         InorderIterator iter = new InorderIterator(root, true);
60         InorderIterator reversedIter = new InorderIterator(root, false);
61         
62         for(int left = iter.next().val, right = reversedIter.next().val; left < right;) {
63             if(left + right == k) {
64                 return true;
65             }
66             else if(left + right < k) {
67                 left = iter.next().val;
68             }
69             else {
70                 right = reversedIter.next().val;
71             }
72         }
73         
74         return false;
75     }
76 }
 1 import java.util.NoSuchElementException;
 2 import java.lang.UnsupportedOperationException;
 3 /**
 4  * Definition for a binary tree node.
 5  * public class TreeNode {
 6  *     int val;
 7  *     TreeNode left;
 8  *     TreeNode right;
 9  *     TreeNode(int x) { val = x; }
10  * }
11  */
12 
13 class InorderIterator implements Iterator<TreeNode> {
14     private TreeNode curr;
15     private Deque<TreeNode> stack;
16     private boolean forward;
17     
18     public InorderIterator(TreeNode root, boolean forward) {
19         this.curr = root;
20         this.stack = new ArrayDeque<>();
21         this.forward = forward;
22     }
23     
24     public boolean hasNext() {
25         return curr!= null || !stack.isEmpty();
26     }
27     
28     public TreeNode next() {
29         // if(!hasNext()) {
30         //     throw new NoSuchElementException("tree run out of elements");
31         // }
32         while(curr != null || !stack.isEmpty()) {
33             if(curr != null) {
34                 stack.push(curr);
35                 if(forward) {
36                     curr = curr.left;
37                 }
38                 else {
39                     curr = curr.right;
40                 }
41             }
42             else {
43                 curr = stack.pop();
44                 TreeNode prev = curr;
45                 if(forward) {
46                     curr = curr.right;
47                 }
48                 else {
49                     curr = curr.left;
50                 }
51                 return prev;
52             }
53         }
54         throw new NoSuchElementException("tree run out of elements");
55     }
56     
57     public void remove() {
58         throw new UnsupportedOperationException();
59     }
60 }
61 
62 class Solution {
63     public boolean findTarget(TreeNode root, int k) {
64         InorderIterator forwardIter = new InorderIterator(root, true);
65         InorderIterator backwardIter = new InorderIterator(root, false);
66         
67         for(int left = forwardIter.next().val, right = backwardIter.next().val; left < right; ) {
68             int sum = left + right;
69             if(sum  ==  k) {
70                 return true;
71             }
72             else if (sum < k) {
73                 left = forwardIter.next().val;
74             }
75             else {
76                 right = backwardIter.next().val;
77             }
78             
79         }
80         
81         return false;
82     }
83 }

 

posted on 2019-04-01 03:47  一直走在路上  阅读(186)  评论(0)    收藏  举报

导航