Skip to content

671. 二叉树中第二小的节点 Easy

给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 2 或 0。如果一个节点有两个子节点的话,那么该节点的值等于两个子节点中较小的一个。

更正式地说,即 root.val = min(root.left.val, root.right.val) 总成立。

给出这样的一个二叉树,你需要输出所有节点中的 第二小的值 。

如果第二小的值不存在的话,输出 -1 。

示例 1:
输入:root = [2,2,5,null,null,5,7]
输出:5
解释:最小的值是 2 ,第二小的值是 5 。

671-1

示例 2:
输入:root = [2,2,2]
输出:-1
解释:最小的值是 2, 但是不存在第二小的值。

671-2

解题思路

输入:二叉树的根节点 root

输出:返回第二小的值

这道题是一个典型的 二叉树遍历 问题。

题目有个特点:每个节点的子节点要么没有,要么恰好有两个,并且如果有两个子节点,那么当前节点一定是这两个子节点中值最小的(也是整棵树的最小值)。

因此,只要这棵树非空,根节点一定是最小值。

我们可以使用深度优先搜索(DFS)遍历整棵树:

  • 当遇到一个节点的值大于最小值(即根节点的值)时,说明它可能是第二小的值;这时直接返回该节点的值(不需要再往下遍历子节点)。
  • 如果遇到的节点值等于最小值,则继续递归遍历左右子树,查找可能的第二小值。
  • 如果左右子树都找不到第二小值,则返回 -1

最后,通过比较左右子树返回的结果,选择较小的那个作为第二小的值。如果都返回 -1,说明整棵树没有第二小的值。

代码实现

python
class Solution:
    def findSecondMinimumValue(self, root: Optional[TreeNode]) -> int:
        # 如果根节点为空,返回 -1
        if not root:
            return -1

        # 记录树的最小值(根节点值,因为是 BST)
        smallest = root.val

        def dfs(node):
            # 如果节点为空,返回 -1
            if not node:
                return -1

            # 如果当前节点值大于最小值,当前值可能是第二小值
            if node.val > smallest:
                return node.val
            
            # 递归遍历左子树和右子树
            left = dfs(node.left)
            right = dfs(node.right)

            # 如果左右子树都返回有效值,取较小的作为候选
            if left != -1 and right != -1:
                return min(left, right)
            # 如果只有一侧有有效值,返回该值;否则返回另一侧的值
            else:
                return left if left != -1 else right
        
        # 返回第二小值
        return dfs(root)
javascript
/**
 * @param {TreeNode} root
 * @return {number}
 */
var findSecondMinimumValue = function(root) {
    if (!root) return -1;

    const smallest = root.val;

    function dfs(node) {
        if (!node) return -1;

        if (node.val > smallest) return node.val;

        const left = dfs(node.left);
        const right = dfs(node.right);

        if (left !== -1 && right !== -1) {
            return Math.min(left, right);
        }

        return left == -1 ? right : left;
    }

    return dfs(root);
};

复杂度分析

时间复杂度:O(n)

空间复杂度:O(h)

链接

671 国际版

671 中文版