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 }
浙公网安备 33010602011771号