题目描述:
- 给定一个二叉搜索树和一个目标结果,如果BST中存在两个元素且他们的和等于给定的目标结果,则返回true。
案例1:
输入:
5
/ \
3 6
/ \ \
2 4 7
Target = 9
输出: True
案例2:
输入:
5
/ \
3 6
/ \ \
2 4 7
Target = 28
输出:False
- 使用Python3
- 算法设计分析:
此类题目是二叉树的类型,适合使用深度优先和广度优先进行索索,我们现在知道二叉树的结点的数据结构,接点值val,左右指针left和right。在这里使用的是深度优先搜索的算法。
首先是定义一个递归退出的条件:这里定义为当目标值-根节点对应的值的差值存在于前面定义的集合set()里面。如果set中存在了,就可以退出递归,否则就将该根节点的值val放入到set中,按照先根后左右的形式进行递归调用,直到遍历完所有的结点,如果存在,就返回true,否则就返回False。
同样道理,使用广度遍历的过程也是一样,不过需要借助队列实现,所以需要额外定义队列。或者使用非递归的方法遍历二叉树的形式也是可以的。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def findTarget(self, root: TreeNode, k: int) -> bool:
# 首先是定义一个Set来存放结果,接着调用深度遍历
res = set()
return self.dfs(root, res, k)
def dfs(self, child, res, target):
if child is None:
return False
val = child.val
# 深度遍历先将目标值与每个节点作比较相减,看该树中是否存在对应的差值,存在就返回True,否则就返回False
if target - val in res:
return True
res.add(val)
# 递归调用左子树和右子树
if self.dfs(child.left, res, target):
return True
elif self.dfs(child.right, res, target):
return True
else:
return False
- 使用Java
- 算法设计分析:
使用一个ArrayList数组,将二叉树中的所有元素存放到数组中,注意这里采用的是中序遍历,根据题目的给出的二叉树,按照中序遍历时候可以得到一个有序数列,按照有序数列的特点,可以使用双指针,两头向中间靠拢,两数字之和大于目标值的,右边左移,小于目标值的左边右移,如果不是有序的数列是不能这样做的!
时间复杂度:O(n), 每个数都会被遍历一遍。
空间复杂度:O(n), 需要开启一个空间为n的数组。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean findTarget(TreeNode root, int k) {
if (root == null)
return false;
ArrayList<Integer> arr = new ArrayList<>();
Inorder(root,arr);
int i = 0;
int j = arr.size()-1;
while(i<j){
if(arr.get(i) + arr.get(j)==k){
return true;
}
// 首尾相加大于目标值,尾部的值大了,要减,否则首部小了,要加
else if(arr.get(i) + arr.get(j)>k){
j--;
}
else{
i++;
}
}
return false;
}
//中序遍历,将树中的值放入到ArrayList里面去,不一定有顺序
public ArrayList Inorder(TreeNode root, ArrayList arr){
if (root != null){
Inorder(root.left, arr);
arr.add(root.val);
Inorder(root.right,arr);
}
return arr;
}
}