653. 两数之和 IV - 输入 BST :「哈希表+树的搜索」&「双指针 + BST 中序遍历」

简介: 653. 两数之和 IV - 输入 BST :「哈希表+树的搜索」&「双指针 + BST 中序遍历」

网络异常,图片无法展示
|


题目描述



这是 LeetCode 上的 650. 只有两个键的键盘 ,难度为 简单


Tag : 「二叉树」、「迭代」、「中序遍历」、「双指针」、「哈希表」、「树的搜索」

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


示例 1:


网络异常,图片无法展示
|


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


示例 2:


网络异常,图片无法展示
|


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


提示:


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


哈希表 + 树的搜索



在递归搜索过程中记录下相应的节点值(使用 Set 集合),如果在遍历某个节点 xx 时发现集合中存在 k - x.valkx.val,说明存在两个节点之和等于 kk,返回 True,若搜索完整棵树都没有则返回 False


代码:


class Solution {
    Set<Integer> set = new HashSet<>();
    public boolean findTarget(TreeNode root, int k) {
        if (root == null) return false;
        if (set.contains(k - root.val)) return true;
        set.add(root.val);
        return findTarget(root.left, k) | findTarget(root.right, k);
    }
}
复制代码


  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(n)O(n)


双指针 + BST 中序遍历



解法一中没有利用 BST 特性,利用 BST 中序遍历有序的特性,我们可以实现类似「双指针」的效果。


起始先让 BST 的最左链和最右链完全入栈,此时栈顶元素为 BST 中的最小值和最大值,分别使用 lr 充当指针代指,根据两指针指向的节点值之和与 kk 的大小关系来指导如何让 lr 移动,l 的移动过程其实就是找下一个比 l.val 更大的值,而 r 的移动过程其实就是找下一个比 r.val 更小的值。


代码:


class Solution {
    public boolean findTarget(TreeNode root, int k) {
        Deque<TreeNode> ld = new ArrayDeque<>(), rd = new ArrayDeque<>();
        TreeNode temp = root;
        while (temp != null) {
            ld.addLast(temp);
            temp = temp.left;
        }
        temp = root;
        while (temp != null) {
            rd.addLast(temp);
            temp = temp.right;
        }
        TreeNode l = ld.peekLast(), r = rd.peekLast();
        while (l.val < r.val) {
            int t = l.val + r.val;
            if (t == k) return true;
            else if (t < k) l = getNext(ld, true);
            else r = getNext(rd, false);
        }
        return false;
    }
    TreeNode getNext(Deque<TreeNode> d, boolean isLeft) {
        TreeNode cur = d.pollLast();
        TreeNode node = isLeft ? cur.right : cur.left;
        while (node != null) {
            d.addLast(node);
            node = isLeft ? node.left : node.right;
        }
        return d.peekLast();
    }
}
复制代码


  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(n)O(n)


最后



这是我们「刷穿 LeetCode」系列文章的第 No.653 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。


在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。


为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:github.com/SharingSour…


在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

相关文章
|
7月前
|
算法
LeetCode刷题---167. 两数之和 II - 输入有序数组(双指针-对撞指针)
LeetCode刷题---167. 两数之和 II - 输入有序数组(双指针-对撞指针)
|
7月前
|
算法 C语言
OJ刷题:求俩个数组的交集(没学哈希表?快排双指针轻松搞定!)
OJ刷题:求俩个数组的交集(没学哈希表?快排双指针轻松搞定!)
|
7月前
|
索引 容器
双指针解决leetcode1两数之和
双指针解决leetcode1两数之和
45 0
|
7月前
|
存储
【每日一题Day132】LC23633合并相似的物品 | 哈希表 排序+双指针
【每日一题Day132】LC23633合并相似的物品 | 哈希表 排序+双指针
56 0
|
7月前
|
C语言 C++
【C++之数组与指针1】随机输入整数存入数组并用指针遍历
【C++之数组与指针1】随机输入整数存入数组并用指针遍历
|
4月前
|
算法 Java
双指针在数组遍历中的应用
文章深入探讨了双指针技术在数组遍历中的应用,通过实战例子详细解释了快慢指针和首尾指针的不同用法,并提供了解决LeetCode相关问题的Java代码实现。
|
7月前
DAY-2 | 哈希表、指针与区间划分:字符种数统计问题
```markdown ## 题干 [牛客网链接](https://www.nowcoder.com/practice/eb94f6a5b2ba49c6ac72d40b5ce95f50) ## 题解 1. **查表法(哈希表)**:利用数组标记出现过的 ASCII 值小于127的字符,首次出现计数,重复则忽略。 2. **指针与区间划分(回头法)**:遍历字符串,对每个字符检查其前所有字符是否重复,重复则不计数。 ## 方法总结 - 哈希表在去重问题中非常实用,可多做相关练习。 - 使用`continue`时注意避免死循环,确保循环变量会改变。 - 多回顾此类问题以巩固理解。 ```
48 2
|
7月前
|
算法
"刷题记录:哈希表+双指针 | leetcode-2465. 不同的平均值数目 "
该文段是一篇关于编程题目的解答,主要讨论如何找到数组中所有不同平均值的个数。作者首先使用排序和哈希集来解决,将数组转为列表排序后,通过双指针计算平均值并存入哈希集以去重。然后,作者发现可以优化方案,通过双指针在排序后的数组中直接计算两数之和,用哈希集记录不重复的和,从而避免实际计算平均值,提高了算法效率。最终代码展示了这两种方法。
62 0
|
7月前
|
算法 C++
双指针算法·两数之和·三数之和
双指针算法·两数之和·三数之和
55 0
|
7月前
|
算法 索引
LeetCode刷题--- 138. 复制带随机指针的链表(哈希表+迭代)
LeetCode刷题--- 138. 复制带随机指针的链表(哈希表+迭代)