//又是考察树的遍历的熟练度,首先可以想到,我们先把树遍历完,把结果集放到一个容器里,再判断2数之和能否等于给定值
//官方题解 用了HashSet,我觉得不错,顺着思路写一个
/*
class Solution {
public boolean findTarget(TreeNode root, int k) {
//首先定义一个Set集合,存放遍历的结果
Set<Integer> set = new HashSet<>();
return search(root,k,set);
}
private boolean search(TreeNode root,int k,Set<Integer> set){
//边界判断,如果root为空,返回false
if(root == null) return false;
//如果不为空,遍历树节点X时,判断在Set中能否寻找到一个值y, 使得 y + x = k,如果有 返回true
if(set.contains(k - root.val)) return true;
//如果不存在这个y值,将X存到set中,继续遍历树
set.add(root.val);
return search(root.left,k,set) || search(root.right,k,set);
}
}
*/
//方法二,将结果集放到一个升序的容器里,使用中序遍历,正好可得一个树的升序序列
class Solution {
public boolean findTarget(TreeNode root, int k) {
//定义一个容器
List<Integer> list = new ArrayList<>();
inOrderTree(root,list);
//此次已经将所有节点的值升序放到list中,用头尾指针法寻找符合条件的俩个节点,若有,返回true
//定义一前一后俩个指针
int left = 0;
int right = list.size() - 1;
while(left < right){
//俩节点的和为sum,与K比较
int sum = list.get(left) + list.get(right);
if(sum == k) return true;
//sum比k大,说明sum需要减小,让right前移,否则令left后移
if(sum > k) right--;
else left++;
}
//遍历完list 还没找到符合条件的俩个节点,返回false
return false;
}
//中序遍历树,递归法 先左子树,根,右子树
private void inOrderTree(TreeNode root,List<Integer> list){
if(root == null) return;
inOrderTree(root.left,list);
list.add(root.val);
inOrderTree(root.right,list);
}
}