每日一题 653. 两数之和 IV - 输入 BST

119 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

一、题目描述

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

示例

示例1: image.jpeg

输入: root = [5,3,6,2,4,null,7], k = 9
输出: true

示例2: image.jpeg

输入: root = [5,3,6,2,4,null,7], k = 28
输出: false

提示

  • 二叉树的节点个数的范围是 [1, 104].
  • -104 <= Node.val <= 104
  • root 为二叉搜索树
  • -105 <= k <= 105

难度:简单

二、思路分析

众所周知,力扣上,简单题是真简单,中等题有些困难,困难题看不懂答案。 此题为简单题,兄弟们可以重拳出击,没错,就是你想到的那种方法,简单粗暴!

题目解析

  1. BST,即二叉搜索树,二叉搜索树的特点就是任何一个结点的左子结点总是小于于自身值,右子结点总是大于自身值。
  2. 如果是在数组中,可以使用遍历方法来判断是否存在符合要求的元素,或者将数组中元素排序后使用左右指针来判断是否存在,因此我们只需要将 BST 转成有序数组,即可通过双指针方法判断结果。
  3. 二叉搜索树 BST 的中序遍历结果得到一个有序集合。

解题思路

通过对题目解析,可以得到如下的题目解答流程

  • 定义一个集合用来存放二叉搜索树中序遍历的序列值
  • 使用递归方法中序遍历二叉搜索树,结点值放入全局集合中,遍历完成得到一个有序集合
  • 定义左右两个指针,分别指向集合两端的最大值和最小值,并不断进行以下判断
    • 如果当前指向的两数之和等于目标值,则直接返回 true;
    • 如果当前指向的两数之和小于目标值,则左侧指针向右移动一位;
    • 如果当前指向的两数之和大于目标值,则右侧指针向左移动一位;
    • 如果左指针位置大于等于右指针位置,说明已经判断所有数字,此时并没有发现等于目标值的两数;
  • 如果程序正常执行结束,则返回false。

三、AC 代码

class Solution {
    List<Integer> list;
    public boolean findTarget(TreeNode root, int k) {
        list = new ArrayList<>();
        
        // 中序递归遍历 BST,得到有序集合
        getNodeValue(root);
        
        // 使用双指针在有序集合中求解两数之和
        int l = 0, r = list.size()-1;
        while(l < r){
            int sum = list.get(l) + list.get(r);
            if(sum == k) return true;
            if(sum < k) l++;
            else r--;
        }
        return false;
    }

    public void getNodeValue(TreeNode root){
        if(root == null) return ;
        if(root.left != null) getNodeValue(root.left);
        list.add(root.val);
        if(root.right != null) getNodeValue(root.right);
    }
}
  • 执行用时:2 ms, 在所有 Java 提交中击败了97.52%的用户
  • 内存消耗:42.1 MB, 在所有 Java 提交中击败了17.12%的用户
  • 通过测试用例:422 / 422

四、总结

知识点

  • BST,二叉搜索树,其中任意结点满足:左子结点比根结点更小,右子结点比根结点更大,其中序遍历得到非减序列
  • 有序数组的判断是否存在两数之和满足目标值,使用左右双指针方法

最后

阳春三月,算法刷起来!LeetCode 每日一题

简单题,不需要考虑太多,开干就是了。