给定一个二叉搜索树的 根节点 root 和一个整数 k , 请判断该二叉搜索树中是否存在两个节点它们的值之和等于 k 。假设二叉搜索树中节点的值均唯一。
示例 1:
输入: root = [8,6,10,5,7,9,11], k = 12
输出: true
解释: 节点 5 和节点 7 之和等于 12
示例 2:
输入: root = [8,6,10,5,7,9,11], k = 22
输出: false
解释: 不存在两个节点值之和为 22 的节点
提示:
二叉树的节点个数的范围是 [1, 104].
-104 <= Node.val <= 104
root 为二叉搜索树
-105 <= k <= 105
注意:本题与主站 653 题相同: https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst/
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/opLdQZ
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
借助 Hash 表,空间复杂度 O(n) ,适用于所有的树,如果是二叉搜索树,太慢了
/**
* 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 {
Map<Integer, Integer> map;
boolean flag;
public boolean findTarget(TreeNode root, int k) {
map = new HashMap<>();
flag = false;
findTrue(root, k);
return flag;
}
public void findTrue(TreeNode root, int k) {
if (root == null) {
return;
}
if (map.containsKey(k - root.val)) {
flag = true;
return;
}
map.put(root.val, map.getOrDefault(root.val, 0) + 1);
findTrue(root.left, k);
findTrue(root.right, k);
}
}
双指针:
定义类似https://blog.csdn.net/weixin_45962741/article/details/122539391?spm=1001.2014.3001.5501
的迭代器,反向和正向即可
充分利用二叉搜索树的性质,找到节点 pre 是最大的点,找到节点 next 是最小的点,双指针法,如果小于 k,让 next 往右走,反之亦然
题目中,Interator 迭代器是从小到大的迭代,能够首先找到最小的点,reverseInterator 能够首先找到最大的点,当二者重合的时候,二分查找结束
/**
* 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) {
Interator interator = new Interator(root);
ReverseInterator reverseInterator = new ReverseInterator(root);
TreeNode next = interator.next();
TreeNode pre = reverseInterator.pre();
while (next != pre) {
if (next.val + pre.val == k) {
return true;
} else if (next.val + pre.val < k) {
next = interator.next();
} else {
pre = reverseInterator.pre();
}
}
return false;
}
}
class Interator {
TreeNode cur;
Stack<TreeNode> stack;
public Interator(TreeNode root) {
cur = root;
stack = new Stack<>();
}
public TreeNode next() {//第一次调用,找到最小的点,不断地往右遍历
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
TreeNode nex = cur;
cur = cur.right;
return nex;
}
}
class ReverseInterator {
TreeNode cur;
Stack<TreeNode> stack;
public ReverseInterator(TreeNode root) {
cur = root;
stack = new Stack<>();
}
public TreeNode pre() {// 第一次调用,找到最大的点,不断地往左遍历
while (cur != null ) {
stack.push(cur);
cur = cur.right;
}
cur = stack.pop();
TreeNode pr = cur;
cur = cur.left;
return pr;
}
}