当前位置: 首页 > article >正文

【递归】8. leetcode 671 二叉树中第二小的节点

题目描述

题目链接:二叉树中第二小的节点
在这里插入图片描述

2 解答思路

注意这句话:该节点的值等于两个子节点中较小的一个
在这里插入图片描述

二叉树的根节点的值是整棵树中最小的值

本道题所要求的是二叉树中第二小的节点。因为根节点是最小的节点,那么我们只需要找到第一个比根节点大的节点就行了。

递归分为三步,接下来就按照这三步来思考问题

第一步:挖掘出相同的子问题  (关系到具体函数头的设计)
第二步:只关心具体子问题做了什么  (关系到具体函数体怎么写,是一个宏观的过程)
第三步:找到递归的出口,防止死递归  (关系到如何跳出递归)

2.1 相同的子问题(函数头设计)

相同的子问题:找二叉树的第二小的节点就是找二叉树左子树的第二小节点和右子树第二小节点。

根据上面的分析,这里需要传递的参数包括三个:

  1. TreeNode* root 二叉树
  2. 根节点的值 int rootvalue
  3. 第二小的节点的值 int& ans

下面是leetcode给的函数头:

    int findSecondMinimumValue(TreeNode* root) {
    }

传递一个二叉树进来,最后返回二叉树中第二小的节点。

我们自己设计的函数头如下:

    void dfs(TreeNode* root, int& ans, int rootvalue)
    {
    }

解释:
1.为什么ans传递引用而rootvalue不传递引用?
因为rootvalue表示的是整个二叉树根节点的值,也就是最小值,这个值是不会改变的,所以直接传递,不需要传递引用。而ans表示第二小的节点的值,这个值会根据不断的递归而改变,直到最终确定,所以要传递引用。

2.返回值为什么是void?
因为答案存储在ans中,不需要返回值

2.2 具体的子问题做了什么(函数体的实现)

根据之前的分析,具体的子问题做的事情:
1.判断当前节点的值是否是第一个大于rootvalue的值,如果是就更新给ans
2.判断左子树和右子树

这里有一个小细节:
当当前节点的值大于ans时,说明从该节点开始的后面的所有节点都大于ans(因为该节点的值是这颗子树中最小的)

正是因为这样的原因,如果当前节点的值大于ans时,就不需要往后递归了。做到了剪枝。

函数的实现:

    void dfs(TreeNode* root, int& ans, int rootvalue)
    {
    //递归的出口
        if (root == nullptr)
            return;
        
        //剪枝
        if (ans != -1 && root->val >= ans)
            return;

        if (root->val > rootvalue)
            ans = root->val;

        dfs(root->left, ans, rootvalue);
        dfs(root->right, ans, rootvalue);
    }

总结

class Solution {
public:
    void dfs(TreeNode* root, int& ans, int rootvalue)
    {
        if (root == nullptr)
            return;
        
        //剪枝
        if (ans != -1 && root->val >= ans)
            return;

        if (root->val > rootvalue)
            ans = root->val;

        dfs(root->left, ans, rootvalue);
        dfs(root->right, ans, rootvalue);
    }

    int findSecondMinimumValue(TreeNode* root) {
        int ans = -1;
        //根节点的值是不会修改的,也是最小的
        int rootvalue = root->val;
        dfs(root, ans, rootvalue);

        return ans;
    }
1. 相同的子问题:找二叉树的第二小的节点就是找二叉树左子树的第二小节点和右子树第二小节点。
2. 具体子问题做了什么:判断当前节点的值是否是第一个大于rootvalue的值,如果是就更新给ans.判断左子树和右子树
3. 递归的出口:当前节点为空。

在这里插入图片描述


http://www.kler.cn/a/323974.html

相关文章:

  • vscode中执行git合并操作需要输入合并commit信息,打开的nano小型文本编辑器说明-
  • 如何在 Ubuntu 上配置 Kotlin 应用环境 ?
  • awk(常用)
  • 2、开发工具和环境搭建
  • FingerprintSimilarity和BulkTanimotoSimilarity的区别
  • 如何实现主备租户的无缝切换 | OceanBase应用实践
  • 1. IP地址介绍
  • SpringCloud无法注册Nacos和配置中心
  • localhost 自动被 redirect 到 https 地址的问题
  • 多输入多输出预测 | NGO-BP北方苍鹰算法优化BP神经网络多输入多输出预测(Matlab)
  • 企业级Windows server服务器技术(1)
  • Token: 数据库、存储系统和API安全的应用
  • pcs集群表决盘故障导致主机reboot
  • @Transactional导致数据库连接数不够
  • 在pycharm中怎样debug一个网页程序
  • 极限基本类型小结
  • 微服务Redis解析部署使用全流程
  • WPF入门教学十八 动画入门
  • C++编程:实现简单的高精度时间日志记录小程序
  • 大厂AI必备数据结构与算法——链表(三)详细文档
  • AI电销机器人是当代电销企业的新宠,智能机器人部署
  • 设计模式之策略设计模式
  • vue仿chatGpt的AI聊天功能--大模型通义千问(阿里云)
  • 鼎跃安全丨多功能气体检测报警系统:工业安全守护者
  • 菱形继承的类对父类的初始化、组合、多态、多态的原理等的介绍
  • C#基础:掌握控制流语句,构建灵活的程序逻辑