leetcode
leetcode 1301 ~ 1350
统计二叉树中好节点的数目

统计二叉树中好节点的数目

难度:

标签:

题目描述

给你一棵根为 root 的二叉树,请你返回二叉树中好节点的数目。

「好节点」X 定义为:从根到该节点 X 所经过的节点中,没有任何节点的值大于 X 的值。

 

示例 1:

输入:root = [3,1,4,3,null,1,5]
输出:4
解释:图中蓝色节点为好节点。
根节点 (3) 永远是个好节点。
节点 4 -> (3,4) 是路径中的最大值。
节点 5 -> (3,4,5) 是路径中的最大值。
节点 3 -> (3,1,3) 是路径中的最大值。

示例 2:

输入:root = [3,3,null,4,2]
输出:3
解释:节点 2 -> (3, 3, 2) 不是好节点,因为 "3" 比它大。

示例 3:

输入:root = [1]
输出:1
解释:根节点是好节点。

 

提示:

  • 二叉树中节点数目范围是 [1, 10^5] 。
  • 每个节点权值的范围是 [-10^4, 10^4] 。

代码结果

运行时间: 102 ms, 内存: 29.8 MB


/*
 * 思路:使用递归的方式和Java Streams来遍历二叉树。
 * 对于每个节点,判断其值是否大于等于路径中的最大值,并对左右子树进行递归处理。
 * 通过递归调用的返回值来统计好节点的数量。
 */
import java.util.stream.Stream;

public class Solution {
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x) { val = x; }
    }

    public int goodNodes(TreeNode root) {
        return goodNodes(root, Integer.MIN_VALUE);
    }

    private int goodNodes(TreeNode node, int maxVal) {
        if (node == null) {
            return 0;
        }
        int good = node.val >= maxVal ? 1 : 0;
        maxVal = Math.max(maxVal, node.val);
        return good + goodNodes(node.left, maxVal) + goodNodes(node.right, maxVal);
    }
}

解释

方法:

本题解采用了深度优先搜索(DFS)的方法来遍历二叉树中的所有节点,并在每个节点处检查其是否为好节点。定义'好节点'为该节点的值不小于从根到该节点路径上的任何节点的值。DFS在每次递归调用时,将当前路径上的最大值作为参数传递,这样可以在遍历到每个节点时,直接与这个最大值进行比较。如果当前节点的值大于或等于这个最大值,那么此节点被认为是好节点,并更新计数器和路径上的最大值。递归遍历左右子树直到所有节点都被访问。

时间复杂度:

O(n)

空间复杂度:

O(h),其中h为树的高度

代码细节讲解

🦆
在DFS递归中,为什么选择负无穷大作为初始的最大值参数?
在深度优先搜索(DFS)中选择负无穷大作为初始的最大值参数,是为了确保根节点能够被计算为好节点。由于好节点的定义是节点的值不小于从根到该节点路径上的任何节点的值,使用负无穷大作为起始比较基准可以保证根节点的值总是大于或等于这个初始值。这样,无论根节点的实际值是多少,它都会被正确地识别为好节点。
🦆
如果二叉树的所有节点值都是非负的,是否有更优的初始最大值选择?
如果已知二叉树的所有节点值都是非负的,则可以将初始最大值设为0而不是负无穷大。这是因为非负值意味着树中的最小可能节点值为0。这样做可以稍微简化比较过程,但实际上对算法的性能提升不大,因为关键操作是节点值的比较,无论比较的是0还是负无穷大,操作的复杂度是相同的。
🦆
在递归调用`dfs(root.left, mx)`和`dfs(root.right, mx)`时,为什么可以直接使用`mx`而不是更新后的最大值?
在递归调用`dfs(root.left, mx)`和`dfs(root.right, mx)`时,可以直接使用`mx`而不是更新后的最大值,因为每个节点路径都是独立的。当我们从一个父节点向下递归到其子节点时,子节点只需与其父节点路径上的最大值进行比较。这保持了递归过程中路径上的最大值的正确性,而不需要在每次递归时都更新传递给左右子树的最大值。每个节点都在其特定路径上独立地考虑,确保了算法的正确性。
🦆
如何处理二叉树中节点值相等的情况,这会对好节点的判断产生什么影响?
在二叉树中,如果存在节点值相等的情况,根据好节点的定义,这些节点仍然可以被视为好节点,只要它们的值不小于从根到该节点路径上的任何其他节点的值。因此,即使两个连续的节点具有相同的值,只要该值不小于任何先前节点的值,这两个节点都可以被算作好节点。这种处理方式确保了算法的包容性和正确性,即使在节点值相等的情况下也能正确地统计好节点的数量。

相关问题