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)

 /**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private boolean findHelper(TreeNode root, int k, Set<Integer> record) {
if(root == null) {
return false;
} if(record.contains(k - root.val)) {
return true;
}
record.add(root.val);
return findHelper(root.left, k, record)
|| findHelper(root.right, k, record);
}
public boolean findTarget(TreeNode root, int k) {
return findHelper(root, k, new HashSet<Integer>());
}
}

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

Time complexity: O(n)

Space complexity: O(n)

 class Solution {
public boolean findTarget(TreeNode root, int k) {
if(root == null) {
return false;
}
Deque<TreeNode> queue = new ArrayDeque<>();
Set<Integer> record = new HashSet<>();
queue.add(root); while(!queue.isEmpty()) {
TreeNode node = queue.pollFirst();
if(record.contains(k - node.val)) {
return true;
}
record.add(node.val);
if(node.left != null) {
queue.offerLast(node.left);
}
if(node.right != null) {
queue.offerLast(node.right);
}
} return false;
}
}

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)

 /**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private void inorderWalk(TreeNode root, List<Integer> nums) {
if(root == null) {
return;
} inorderWalk(root.left, nums);
nums.add(root.val);
inorderWalk(root.right, nums);
} public boolean findTarget(TreeNode root, int k) {
List<Integer> nums = new ArrayList<>(); inorderWalk(root, nums); for(int left = 0, right = nums.size()-1; left < right; ) {
int sum = nums.get(left) + nums.get(right);
if(sum == k) {
return true;
}
else if(sum < k) {
++left;
}
else {
--right;
}
} return false;
}
}

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)

 import java.util.NoSuchElementException;
import java.lang.UnsupportedOperationException;
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/ class InorderIterator implements Iterator<TreeNode> {
private TreeNode curr;
private Deque<TreeNode> stack;
private boolean forward; public InorderIterator(TreeNode root, boolean forward) {
this.curr = root;
this.stack = new ArrayDeque<>();
this.forward = forward;
} public boolean hasNext() {
return curr!= null || !stack.isEmpty();
} public TreeNode next() {
if(!hasNext()) {
throw new NoSuchElementException("tree run out of elements");
}
while(curr != null) {
stack.push(curr);
if(forward) {
curr = curr.left;
}
else {
curr = curr.right;
}
}
curr = stack.pop();
TreeNode prev = curr;
if(forward) {
curr = curr.right;
}
else {
curr = curr.left;
}
return prev;
} public void remove() {
throw new UnsupportedOperationException();
}
} class Solution {
public boolean findTarget(TreeNode root, int k) {
InorderIterator iter = new InorderIterator(root, true);
InorderIterator reversedIter = new InorderIterator(root, false); for(int left = iter.next().val, right = reversedIter.next().val; left < right;) {
if(left + right == k) {
return true;
}
else if(left + right < k) {
left = iter.next().val;
}
else {
right = reversedIter.next().val;
}
} return false;
}
}
 import java.util.NoSuchElementException;
import java.lang.UnsupportedOperationException;
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/ class InorderIterator implements Iterator<TreeNode> {
private TreeNode curr;
private Deque<TreeNode> stack;
private boolean forward; public InorderIterator(TreeNode root, boolean forward) {
this.curr = root;
this.stack = new ArrayDeque<>();
this.forward = forward;
} public boolean hasNext() {
return curr!= null || !stack.isEmpty();
} public TreeNode next() {
// if(!hasNext()) {
// throw new NoSuchElementException("tree run out of elements");
// }
while(curr != null || !stack.isEmpty()) {
if(curr != null) {
stack.push(curr);
if(forward) {
curr = curr.left;
}
else {
curr = curr.right;
}
}
else {
curr = stack.pop();
TreeNode prev = curr;
if(forward) {
curr = curr.right;
}
else {
curr = curr.left;
}
return prev;
}
}
throw new NoSuchElementException("tree run out of elements");
} public void remove() {
throw new UnsupportedOperationException();
}
} class Solution {
public boolean findTarget(TreeNode root, int k) {
InorderIterator forwardIter = new InorderIterator(root, true);
InorderIterator backwardIter = new InorderIterator(root, false); for(int left = forwardIter.next().val, right = backwardIter.next().val; left < right; ) {
int sum = left + right;
if(sum == k) {
return true;
}
else if (sum < k) {
left = forwardIter.next().val;
}
else {
right = backwardIter.next().val;
} } return false;
}
}

最新文章

  1. 手持移动扫描终端 PDA移动开单系统-批发零售管理
  2. java 内部类与外部类的区别
  3. arcgis desktop 10.1 license manager无法启动问题解决
  4. ASP.NET MVC 4 (三) 过滤器
  5. Android下海康实时视频解码
  6. python抓取汇率
  7. 小白日记52:kali渗透测试之Web渗透-HTTPS攻击(Openssl、sslscan、sslyze、检查SSL的网站)
  8. GDI+绘制文本
  9. Android中Socket大文件断点上传
  10. 007.Compiled
  11. [每日一题] 11gOCP 1z0-052 :2013-09-25 Lock ――for update.................................C23
  12. 0. chromium源代码分析 - 序
  13. MicroPython+北斗+GPS+GPRS:TPYBoardv702短信功能使用说明
  14. JS 循环定时的一些思考
  15. VisualStudio移动开发(C#、VB.NET)Smobiler开发平台——BarcodeView控件的使用方式,.Net移动开发
  16. 浅谈HTTP协议与TCP协议
  17. ymPrompt,jcs缓存架构
  18. 实现C语言字符串操作的库函数 包括基本的字符串复制 字符串长度 字符串比较等多种函数(C代码)
  19. [转帖]脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?
  20. Docker基础速成(一)

热门文章

  1. Shiro在Spring session管理
  2. bpm 学习笔记一
  3. python找包的路径(找不到自定义包的问题解决)
  4. zookeeper报错: org.I0Itec.zkclient.exception.ZkMarshallingError: java.io.EOFException
  5. 手机端用swiper组件 轮播图设置后右侧出现空白 及 部分手机浏览器打开网页空白
  6. Linux下常用的编辑文件与保存命令
  7. 【转】 UI自动化测试的关注点
  8. 专项测试——移动app安装包检测
  9. f5备份与还原
  10. echarts中国地图散点涟漪效果