LeetCode--653.两数之和 IV -输入BST

两数之和 IV -BST

给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。

示例1

输入: 
    5
   / \
  3   6
 / \   \
2   4   7

Target = 9

输出: True

示例2

输入: 
    5
   / \
  3   6
 / \   \
2   4   7

Target = 28

输出: False

方法一

思路

Set + 递归之倒推法: 准备一个Set集合当做容器,将二叉搜索树的所有数据放入Set集合中,递归每一个元素节点,判断集合中是否有一个数加上本节点的值为目标数据,有则返回true,如果递归遍历结束还没有返回true则返回false。

代码
// 倒推法
    // 遍历树结构时   x是当前节点, y=k-x 是要找的第二个节点  是否存在
    //    遍历过程用容器存储  以方便快速查找   set
    // 时间复杂度O(n)   空间复杂度O(n)
    public boolean findTarget(TreeNode root, int k) {
        Set<Integer> set = new HashSet<>();
        return f(root, k, set);
    }
    public boolean f(TreeNode root, int k, Set<Integer> set) {
        // 判断如果节点为空则返回false
        if (root == null) {
            return false;
        }
        // 判断集合中是否有值与当前节点的值相加为k
        int temp = k - root.val;
        if (set.contains(temp)) {
            return true;
        }
        // 如果没有则将当前节点的值存入集合继续遍历
        set.add(root.val);
        boolean left = f(root.left, k, set);
        boolean right = f(root.right, k, set);
        // 当递归结束,返回left分支或right分支(有一个返回true则符合结果)
        return left || right;
    }

方法二

思路

队列迭代: 使用队列迭代代替递归遍历,还是将二叉搜索树的各个节点值存入Set集合,通过队列依次迭代判断Set集合中是否存在于当前节点值相加为目标数组。

代码
// 使用迭代
    //   用队列存储遍历的节点   处理一个节点后移除  当队列为空时  处理完成
    //   时间复杂度O(n)   空间复杂度O(n)
    public boolean findTarget1(TreeNode root, int k) {
        Set<Integer> set = new HashSet<>();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        // 只要队列不为空则一直循环
        while (!queue.isEmpty()) {
            // 将当前节点取出,判断set中是否有与其相加为k的数据
            TreeNode node = queue.poll();
            if (set.contains(k - node.val)) {
                return true;
            }
            set.add(node.val);
            // 接着向下寻找
            if (node.left != null) {
                queue.add(node.left);
            }
            if (node.right != null) {
                queue.add(node.right);
            }
        }
        return false;
    }

方法三

思路

二叉树转有序列表双指针法: 这个方法优化了空间复杂度,因为二叉搜索树是有序的,先将二叉搜索树中序遍历转化为有序列表,然后双指针法找出结果,【有序数组两数之和 】,所谓双指针法就是定义两个指针,一个指向下表为0,另一个指向下标为长度-1,如果两个指针所指向的值相加大于目标值,则后面的指针自减,如果两个指针所指的指小于目标值,则前面的指针自增。如果当前面的指针大于等于后面的指针时,则说明条件不成立退出循环。

代码
// 二叉搜索树  可以转化为有序列表
    //    在有序列表中  快速找到两个满足条件的值   使用的是头尾两个指针
    // 双指针法
    public boolean findTarget2(TreeNode root, int k) {
        List<Integer> list = new ArrayList<>();
        orderly(root, list);

        int left = 0;
        int right = list.size() - 1;

        while (left < right) {
            int s = list.get(left) + list.get(right);
            if (s < k) {
                left++;
            }
            if (s > k) {
                right--;
            }
            if (s == k) {
                return true;
            }
        }
        return false;
    }

    public void orderly(TreeNode root, List<Integer> list) {
        if (root == null) {
            return;
        }
        orderly(root.left, list);
        list.add(root.val);
        orderly(root.right, list);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值