leetcode
leetcode 1001 ~ 1050
查找两棵二叉搜索树之和

查找两棵二叉搜索树之和

难度:

标签:

题目描述

代码结果

运行时间: 49 ms, 内存: 19.6 MB


/*
 题目思路:
 1. 利用Java Stream API可以更简洁地处理集合数据。
 2. 我们可以先将两棵树的节点值分别收集到两个集合中。
 3. 然后使用流操作检查是否存在一对值,它们的和为目标值target。
 */

import java.util.*;
import java.util.stream.*;

class Solution {
    public boolean twoSumBSTs(TreeNode root1, TreeNode root2, int target) {
        // 将两棵树的节点值分别收集到集合中
        Set<Integer> set1 = new HashSet<>();
        Set<Integer> set2 = new HashSet<>();
        collectValues(root1, set1);
        collectValues(root2, set2);
        // 使用流操作检查是否存在一对值使得它们的和为目标值
        return set1.stream().anyMatch(val -> set2.contains(target - val));
    }

    private void collectValues(TreeNode node, Set<Integer> set) {
        if (node == null) return;
        set.add(node.val);
        collectValues(node.left, set);
        collectValues(node.right, set);
    }
}

解释

方法:

该题解采用了一种混合的深度优先搜索(DFS)和哈希表的方法来解决问题。首先,通过对第一棵二叉搜索树进行DFS遍历,将每个节点的补数(即 target 减去该节点的值)存储在一个哈希表中。然后,对第二棵树进行DFS遍历,查看每个节点的值是否已经存在于哈希表中。如果存在,说明存在两个节点的值加和为 target,返回 True。否则,继续搜索直到遍历完整棵树。

时间复杂度:

O(n + m)

空间复杂度:

O(n)

代码细节讲解

🦆
在混合使用DFS和哈希表的方法中,你是如何保证哈希表中存储的补数不会与第二棵树的非目标节点的值冲突?
在这种方法中,实际上我们并不能保证哈希表中存储的补数不会与第二棵树的非目标节点的值发生冲突。这是因为哈希表存储的是从第一棵树中计算出的所有可能与目标值相加得到target的补数。如果第二棵树中存在一个值,它恰好也是某个非目标节点的值但与target的另一个补数相等,这种情况在理论上是可能的。但这种情况在实际应用中相对少见,尤其是当节点值分布较为均匀时。此外,目标是找到是否存在至少一对满足条件的节点对,一旦找到这样的对,算法就会停止,因此即使有冲突,也不会影响结果的正确性。
🦆
为什么选择先对第一棵树进行补数存储,然后再对第二棵树进行检查,这样的顺序是否可以调换?如果调换,对算法会有什么影响?
选择哪棵树先进行补数存储取决于树的结构和大小。通常,选择较小或结构较为简单的树进行补数存储是更有效的,因为这将减少哈希表中的条目数量,从而优化查找速度。如果调换顺序,对于大多数情况,算法的效率和最终结果不会受到影响。然而,如果一棵树显著大于另一棵,将较小的树用于构建哈希表会更优,因为这样可以减少内存使用和潜在的查找时间。
🦆
在算法中,如果第二棵树的某个节点的值已经在哈希表中找到匹配,是否还需要继续遍历该节点的子树?
理论上,一旦在第二棵树中找到一个节点的值在哈希表中匹配成功,就意味着已经找到了一个符合条件的节点对,可以立即返回True,因此不需要继续遍历该节点的子树。然而,如果问题需要找到所有满足条件的节点对,则需要继续遍历。在本题中,我们只需要找到至少一对符合条件的节点,因此找到匹配后即可停止进一步搜索。
🦆
在哈希表中存储补数而不是节点的原始值有什么特别的考量?这种方法对查找速度有何影响?
在哈希表中存储补数而不是节点的原始值主要是为了直接与第二棵树节点的值进行比较,这样可以快速检查是否存在两个值的和等于目标值。这种方法可以显著提高查找速度,因为它允许算法在遍历第二棵树时直接检查当前节点值是否已在哈希表中,从而即刻确定是否找到了匹配的节点对,避免了额外的计算或查找步骤。

相关问题

两数之和 IV - 输入二叉搜索树

给定一个二叉搜索树 root 和一个目标结果 k,如果二叉搜索树中存在两个元素且它们的和等于给定的目标结果,则返回 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, 104].
  • -104 <= Node.val <= 104
  • 题目数据保证,输入的 root 是一棵 有效 的二叉搜索树
  • -105 <= k <= 105