手撸二叉树之二叉树中第二小的节点

举报
HelloWorld杰少 发表于 2022/09/19 12:37:12 2022/09/19
【摘要】 Hello, 大家好,今天给大家带来的关于二叉树相关的算法题是求二叉树中第二小的节点,正文如下: 题目给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为2或0。如果一个节点有两个子节点的话,那么该节点的值等于两个子节点中较小的一个。更正式地说,root.val = min(root.left.val, root.right.val) 总成立。给出这样的一个二叉树,你需...

Hello, 大家好,今天给大家带来的关于二叉树相关的算法题是求二叉树中第二小的节点,正文如下:

题目

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

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

给出这样的一个二叉树,你需要输出所有节点中的第二小的值。如果第二小的值不存在的话,输出 -1 。

示例1:

image

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

示例2:

image

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

提示:

  • 树中节点数目在范围 [1, 25] 内
  • 1 <= Node.val <= 231 - 1
  • 对于树中每个节点 root.val == min(root.left.val, root.right.val)

思路分析

根据题目意思,我们可以得出这样的结论:对于二叉树中的任意节点 x,x 的值不大于以 x 为根的子树中所有节点的值,所以说二叉树的根节点的值为所有节点中的最小值。

因此,我们可以对整棵二叉树进行遍历,找出比根节点大的最小值,即为所有节点中的第二小的值。

我们可以使用深度优先搜索的方法对二叉树进行遍历。

因为 root.val 是树中最小的,所以遍历到任何一个节点的 val ,都是严格大于 root.val 的。

当找到这样一些节点时,我们记录最小值。由于任意节点的val都是左右子树中的最小值,所以可以直接返回,不用继续递归搜索子树。

代码实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int ans = Integer.MAX_VALUE;
    boolean find = false;
    public int findSecondMinimumValue(TreeNode root) {
        if (root.left == null) return -1;
        // 第一个最小值必须为 root.val 
        int val = root.val;

        helper(root, val);
        return !find ? -1 : ans;
    }

    public void helper(TreeNode r, int val) {
        // 因为每个节点的子节点数量只能为0或者2
        // 所以当为null时,就可以直接 return
        if (r == null)  return ;

        // 因为root.val是树中最小的,所以遍历到任何一个节点的val不等于root.val,
        // 都是大于root.val的。当找到这样一些节点时,我们记录最小值。由于任意节点
        // 的val都是左右子树中的最小值,所以可以直接返回,不用继续递归搜索子树。
        if (r.val != val) {
            ans = Math.min(r.val, ans);
            find = true;
            return;
        }

        helper(r.left, val);
        helper(r.right, val);
    }
}

最后

复杂度分析

  • 时间复杂度:O(n),其中 n 是二叉树中的节点个数。我们最多需要对整棵二叉树进行一次遍历。

  • 空间复杂度:O(n)。我们使用深度优先搜索的方法进行遍历,需要使用的栈空间为 O(n)。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。