3、两数之和IV-输入BST

题目描述:

  • 给定一个二叉搜索树和一个目标结果,如果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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值