leetcode
leetcode 251 ~ 300
最接近的二叉搜索树值

最接近的二叉搜索树值

难度:

标签:

题目描述

代码结果

运行时间: 23 ms, 内存: 18.0 MB


/* 
 * Problem: Closest Binary Search Tree Value
 * Approach using Java Streams:
 * 1. Convert the BST to a list using an in-order traversal.
 * 2. Use Java Streams to find the closest value to the target.
 */
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
 
public class Solution {
    public int closestValue(TreeNode root, double target) {
        // In-order traversal to convert BST to a sorted list
        List<Integer> values = new ArrayList<>();
        inOrderTraversal(root, values);
        // Find the closest value using Streams
        return values.stream()
                .min((a, b) -> Double.compare(Math.abs(a - target), Math.abs(b - target)))
                .orElseThrow(() -> new IllegalArgumentException("Tree is empty"));
    }
 
    private void inOrderTraversal(TreeNode node, List<Integer> values) {
        if (node != null) {
            inOrderTraversal(node.left, values);
            values.add(node.val);
            inOrderTraversal(node.right, values);
        }
    }
}

解释

方法:

该题解的思路是使用递归的方式对二叉搜索树进行遍历。首先定义一个内部函数calDiff,用于计算当前节点值与目标值之间的差值的绝对值,并将节点值和差值作为元组存储在nodeVal列表中。然后根据目标值与当前节点值的大小关系,选择递归遍历左子树或右子树。最后对nodeVal列表按照差值和节点值进行排序,返回差值最小的节点值。

时间复杂度:

O(nlogn)

空间复杂度:

O(n)

代码细节讲解

🦆
在你的递归函数`calDiff`中,当遇到`root`为`None`时,函数返回`None`。这种处理对最终结果有什么影响?
在递归函数`calDiff`中,当`root`为`None`时返回`None`是一种常见的递归终止条件,用于处理空树或者到达叶子节点的子节点。这种处理确保了递归能够在没有更多节点可遍历时正确结束。对于最终结果没有直接影响,因为我们收集的是非空节点的值和差值,而返回`None`只是表示停止在当前路径上的进一步遍历。
🦆
为何选择在每个递归调用结束后对`nodeVal`列表进行排序而不是在插入时就维护一个有序列表?
在递归调用结束后对`nodeVal`列表进行排序是出于简化代码逻辑和降低实现复杂度的考虑。虽然在插入时维护一个有序列表(例如使用优先队列)可以在某些情况下提高效率,但它可能需要更复杂的数据结构和额外的逻辑来确保正确性。在这种情况下,由于我们不知道会收集多少节点数据,统一在收集完后排序是一个简单且有效的策略。
🦆
在排序操作中,使用了元组的第二个元素(差值)作为主要的排序关键字,如果存在多个节点值与目标值差值相同,选择最小的节点值作为返回值的原则是否总是适用?
使用差值作为主要排序关键字,并在差值相同的情况下选择最小的节点值,是一个合理的选择,特别是在没有其他优先级指示的情况下。这种方法确保了即使多个节点具有相同的差值,也能返回一个一致和可预测的结果。然而,这是否是最佳选择可能取决于具体的应用场景。在某些情况下,可能需要根据实际需要选择最大的节点值或其他属性。
🦆
你的解法中遍历了整个二叉搜索树,是否有更优的方法只遍历到必要的部分就停止?
是的,存在更优的方法利用二叉搜索树的性质来减少遍历的节点数。可以在遍历过程中维护一个当前最接近的值,只向可能包含更接近目标值的子树方向递归。例如,如果目标值小于当前节点值,只递归访问左子树;如果目标值大于当前节点值,只递归访问右子树。这种方法利用了二叉搜索树的有序性质,减少了不必要的遍历,从而提高了效率。

相关问题

完全二叉树的节点个数

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

 

示例 1:

输入:root = [1,2,3,4,5,6]
输出:6

示例 2:

输入:root = []
输出:0

示例 3:

输入:root = [1]
输出:1

 

提示:

  • 树中节点的数目范围是[0, 5 * 104]
  • 0 <= Node.val <= 5 * 104
  • 题目数据保证输入的树是 完全二叉树

 

进阶:遍历树来统计节点是一种时间复杂度为 O(n) 的简单解决方案。你可以设计一个更快的算法吗?

最接近的二叉搜索树值 II

最接近的二叉搜索树值 II

二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点 root 和一个整数值 val

你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

 

示例 1:

输入:root = [4,2,7,1,3], val = 2
输出:[2,1,3]

示例 2:

输入:root = [4,2,7,1,3], val = 5
输出:[]

 

提示:

  • 树中节点数在 [1, 5000] 范围内
  • 1 <= Node.val <= 107
  • root 是二叉搜索树
  • 1 <= val <= 107