题目来源:https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst/
给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。
测试用例中的树按层遍历为[5,3,6,2,4,null,7]
测试用例表示为(包含多个测试用例):
[5,3,6,2,4,null,7] 9
[5,3,6,2,4,null,7] 28
[2,1,3] 4
[2,0,3,-4,1] -1
二叉搜索树的性质:
- 可以是一颗空树
- 若存在左子树,则左子树所有节点的值都小于(是小于,不包括等于)根节点的值,若存在右子树,则根节点的值大于右子树所有节点的值
结合二叉搜索树的性质,我们可以想到,二叉搜索树的中序遍历是一个递增的有序数列。
得出思路:
- 中序遍历二叉搜索树,得到一个数组,这里用Vector存放树节点值,因为不确定树节点的个数,否则使用数组更方便,设为v。
- 从v值查找和数,若找到返回true,找不到返回false(为方便,下面将向量v用数组的形式进行表示)
从v的最后一个值开始v[j](j=n-1),比较v[j]和target/2的大小,
1)若v[j]<target/2直接返回false(因为v[j]是最大的值,若v[j]小于target/2,在v的其他值一定小于target/2,肯定是没有两个数的和等于target。)
2)若v[j]>target/2则对比v[j]+v[i](i=0),
2.1)若v[j]+v[i]=target,返回true;
2.2)若v[j]+v[i]<target,则i++;
2.3)若v[j]+v[i]>target,则j--
java实现:
public boolean findTarget(TreeNode root, int k) {
Vector v = new Vector();
traverse1(root,k,v);
return find(v,k);
}
private void traverse(TreeNode root, int k, Vector v){
if(root == null) return;
if(root.left != null){
traverse(root.left, k, v);
}
v.addElement(root.val);
//System.out.print(root.val+" ");
if(root.right != null){
traverse(root.right, k, v);
}
}
private boolean find(Vector v, int k){
int n = v.size();
if(n > 0){
for(int j = n-1; j>0; j--){
if((int)v.get(j) > k/2){ // 2)
for(int i=0; i<j; i++){
int add = (int)v.get(j) + (int)v.get(i);
if(add == k){
return true; // 2.1)
}else if(add > k){
break; //2.3)
}
}
}else{
return false;// 1)
}
}
}
return false;
}
该算法的执行时间效率很高,但消耗的内存多,因为使用了vector存放数据(注意要在LeetCode上要import vector)。
要想在IDE(eclipse)中调试,请参考博客《如何在IDE(eclipse)中debug LeetCode的树算法》
为了得到而努力
2019-04-05
转载请注明来处