代码随想录算法训练营:19/60

非科班学习算法day19 | LeetCode530:二叉搜索树的最小绝对差 ,Leetcode501:二叉搜索树的众数 ,Leetcode236:二叉树的最近公共祖先 

目录

介绍

一、LeetCode题目

1.LeetCode530:二叉搜索树的最小绝对差 

题目解析

 2.Leetcode501: 二叉搜索树的众数 

题目解析

3.Leetcode236:二叉树的最近公共祖先

题目解析

 

总结


介绍

包含LC的两道题目,还有相应概念的补充。

相关图解和更多版本:

代码随想录 (programmercarl.com)https://programmercarl.com/#%E6%9C%AC%E7%AB%99%E8%83%8C%E6%99%AF


一、LeetCode题目

1.LeetCode530:二叉搜索树的最小绝对差 

题目链接:530. 二叉搜索树的最小绝对差 - 力扣(LeetCode)

题目解析

       首先要知道,最小绝对差会出现在什么位置,因为限定了任意两个数的差值,但根据二叉搜索树的特点,如果用相隔远的两个数相减,差值一定大于相邻两数,所以问题退化到中序遍历相邻两数计算最小差值。

        可以采用设置临时指针pre来一遍遍历就完成。

        或者直观的方法,中序遍历记录元素信息,将得到的数组进行遍历。

 c++代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
public:
    // 需要中序遍历,最小差出现在前后两个数中间,所以可以设置临时指针
    // 创建临时指针
    TreeNode* pre = nullptr;
    // 创建最大值
    int min_dif = INT_MAX;
    // 中序遍历函数
    void dis(TreeNode* root) {
        if (!root)
            return;
        // 左
        dis(root->left);
        // 处理
        if (pre) {
            int cur_dif = abs(pre->val - root->val);
            min_dif = min(min_dif, cur_dif);
        }
        pre = root;
        dis(root->right);
        return;
    }
    int getMinimumDifference(TreeNode* root) {
        dis(root);
        return min_dif;
    }
};

比较直观的c++代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
public:
    void dis(TreeNode* root, vector<int>& vec) {
        if (!root)
            return;
        dis(root->left, vec);
        vec.push_back(root->val);
        dis(root->right, vec);
        return;
    }
    int getMinimumDifference(TreeNode* root) {
        vector<int> result;
        dis(root, result);
        int min_num = INT_MAX;
        for (int i = 0; i < result.size() - 1; ++i) {
            min_num = min(min_num, result[i + 1] - result[i]);
        }
        return min_num;
    }
};

 2.Leetcode501: 二叉搜索树的众数 

题目链接:501. 二叉搜索树中的众数 - 力扣(LeetCode)

题目解析

       个人认为很喜欢的一道题目,我遵循的也是双指针思想:中序遍历,实时更新最大长度,然后将最大长度对应的结果放到返回数组中,但是遇到了问题:

        1.最大初始长度设置为0,这样一开始的根节点怎么处理,因为实际上最小的长度应该是1

        2.在一次遍历的过程中,如果发现最大值就记录,其实不能保证这是全过程的最大长度(后面的可能会有更长的),那么弹出的条件怎么设置。
       

 C++代码如下: 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
public:
    // 设置前一指针
    TreeNode* pre = nullptr;
    // 设置最大长度
    int max_len = 0;
    // 设置当前长度
    int len = 0;
    vector<int> res;
    void dis(TreeNode* root) {
        if (!root)
            return;
        dis(root->left);

        if (!pre)
            len = 1;
        else if (pre->val == root->val) {
            len++;
        } else
            len = 1;

        if (len == max_len) {
            res.push_back(root->val);
        }
        if (len > max_len) {
            max_len = len;
            res.clear();
            res.push_back(root->val);
        }
        pre = root;

        dis(root->right);
        return;
    }
    vector<int> findMode(TreeNode* root) {
        max_len = 0;
        len = 0;
        res.clear();
        pre = nullptr;

        dis(root);
        return res;
    }
};

关于这两个问题:1.pre指针还指向空的时候就把指针设置为1,注意在长度没有增加时候else情况,要把长度重置为1,这点很重要。其实我认为也可以直接初始化就设置为1;

2.没有必要弹出,因为如果后面搜索到更长的长度,我们只需要清空当前结果就可以了,前面的结果都不是想要的。

  

3.Leetcode236:二叉树的最近公共祖先

题目链接:236. 二叉树的最近公共祖先 - 力扣(LeetCode)

题目解析

       一开始理解的很艰难,因为涉及到类似于从底部向上检索的过程,这里面是一定有回溯。首先纠正一个问题,就是我在尝试用bool的返回类型辅助函数,但是我写的过程中发现我无法用这个函数来记录或者说返回节点信息,除非是用pair来记录存在信息和节点信息,那样理解是相对好了,但是写法上复杂度大大增加。

        现在的写法的关键就是,还是后序遍历的模板,但是在回溯过程中(就是return!)当不存在我们需要检索的值时候,返回空指针,这样也可以帮助我们bool判断!

        标记一下,相关的有需要下向上搜索的题目,后期再比对总结:树的最大深度/最小深度,树的直径,路径总和问题

C++代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (!root)
            return NULL;
        if (root->val == p->val || root->val == q->val)
            return root;

        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        TreeNode* right = lowestCommonAncestor(root->right, p, q);
        if (left && right)
            return root;
        if (!left && right)
            return right;
        if (left && !right)
            return left;
        else
            return NULL;
    }
};

注意点1:代码虽然看起来简单,但是这个中止条件之所以没有放在后面是因为,遵循的逻辑是先向下搜索,搜索到需要值,返回这个节点信息到上一层,这样就记录了节点信息。

而后面的处理是针对于一层递归左右结束之后中节点的处理逻辑,两者是不一样的,不要混淆。

 

总结


补打卡第19天,坚持!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/746144.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue elementui简易侧拉栏的使用

如图所示&#xff0c;增加了侧拉栏&#xff0c;目的是可以选择多条数据展示数据 组件&#xff1a; celadon.vue <template><div class"LayoutMain"><el-aside :width"sidebarIsCollapse ? 180px : 0px" class"aside-wrap">…

MD5加密接口

签名算法 app_key和app_secret由对方系统提供 MD5_CALCULATE_HASH_FOR_CHAR&#xff08;中文加密与JAVA不一致&#xff09; 代码&#xff1a; *获取传输字段名的ASCII码&#xff0c;根据ASCII码对字段名进行排序SELECT * FROM zthr0051WHERE functionid iv_functionidINTO …

AI音乐大模型:深度剖析创意与产业的双重变革

随着AI技术的飞速发展&#xff0c;音乐大模型在最近一个月内纷纷上线&#xff0c;这一变革性技术不仅颠覆了传统的音乐创作方式&#xff0c;更是对整个音乐产业及创意产业带来了深远的影响。本文将从多个维度出发&#xff0c;深度剖析AI音乐大模型对创意与产业的双重变革。 一、…

多模态能力评估新篇章:MMStar引领大型视觉语言模型评估新标准

随着大模型&#xff08;LLMs&#xff09;的快速发展&#xff0c;将视觉模态整合进LLMs以提升模型的交互能力已成为研究的热点。这些大型视觉语言模型&#xff08;LVLMs&#xff09;不仅展现出强大的视觉感知和理解能力&#xff0c;还能够通过对话与用户互动&#xff0c;提供更丰…

Matlab|【免费】含氢气氨气综合能源系统优化调度

目录 主要内容 部分代码 结果一览 下载链接 主要内容 该程序参考《_基于氨储能技术的电转氨耦合风–光–火综合能源系统双层优化调度》模型&#xff0c;对制氨工厂、风力发电、电制氢、燃气轮机、火电机组等主体进行建模分析&#xff0c;以火电机组启停成本、煤耗…

尚硅谷vue2的todolist案例解析,基本概括了vue2所有知识点,结尾有具体代码,复制粘贴学习即可

脚手架搭建 1-初始化脚手架&#xff08;全局安装&#xff09; npm install -g vue/cli2-切换到创建项目的空目录下 vue create xxxx整体结构 整体思路 App定义所有回调方法 增删改查 还有统一存放最终数据&#xff0c;所有子组件不拿数据&#xff0c;由App下发数据&#xf…

Spring Boot 集成 H2 数据库

1. 引言 Spring Boot 以其简洁的配置和快速开发能力&#xff0c;成为现代微服务架构的首选框架之一。而H2数据库作为一个轻量级的内存数据库&#xff0c;非常适合开发阶段作为嵌入式数据库进行单元测试和功能验证。本文将手把手教你如何在Spring Boot项目中集成H2数据库&#…

Mybatis 到 MyBatisPlus

Mybatis 到 MyBatisPlus Mybatis MyBatis&#xff08;官网&#xff1a;https://mybatis.org/mybatis-3/zh/index.html &#xff09;是一款优秀的 持久层 &#xff08;ORM&#xff09;框架&#xff0c;用于简化JDBC的开发。是 Apache的一个开源项目iBatis&#xff0c;2010年这…

DC/AC电源模块一种效率与可靠性兼备的能源转换解决方案

DC/AC电源模块都是一种效率与可靠性兼备的能源转换解决方案 DC/AC电源模块是一种能够将直流电源&#xff08;DC&#xff09;转换为交流电源&#xff08;AC&#xff09;的设备。它在现代电子设备中扮演着非常重要的角色&#xff0c;因为许多设备需要交流电源才能正常运行。无论…

VS Code修改菜单栏字体大小

修改方法 打开VS Code&#xff0c;快捷键 CtrlShiftP&#xff0c;在弹出的输入框中输入 setting&#xff0c;找到带有JSON的一项&#xff0c;如图所示&#xff1a; 原文链接 window.zoomLevel 前后变化 终端字体大小 File -> Preferences -> Settings -> Features…

云计算运维工程师的突发状况处理

云计算运维工程师在应对突发的故障和紧急情况时,需要采取一系列迅速而有效的措施来最小化服务中断的时间并恢复系统的稳定性。 以下是一些关键步骤和策略: 快速响应: 立即识别并确认故障的性质和范围。通知团队成员和相关的利益相关者,确保所有人了解当前情况。故障诊断:…

迅为iTOP-2K1000开发板龙芯中科国产64位Loognix主板

硬件配置 国产龙芯处理器&#xff0c;双核64位系统&#xff0c;板载2G DDR3内存&#xff0c;流畅运行Busybox、Buildroot、Loognix、QT5.12 系统! 接口全板载4路USB HOST、2路千兆以太网、2路UART、2路CAN总线、Mini PCIE、SATA固态盘接口、4G接口、GPS接口WIF1、蓝牙、Mini H…

环路滤波器

块效应产生的原因 块效应指视频边界不连续的变化,我们在观看视频的时候,在运动剧烈的场景常能观察到图像出现小方块,小方块在边界处呈现不连续的效果(如下图),这种现象被称为块效应(blocking artifact)。 造成这种现象的主要原因有两点: DCT量化误差导致运动补偿导致…

工业网关的功能与作用解析-天拓四方

在工业4.0和智能制造的时代背景下&#xff0c;工业网关作为连接现场设备与云端平台的桥梁&#xff0c;正发挥着日益重要的作用。它不仅为工业设备的远程监控和管理提供了可能&#xff0c;还为企业实现数字化转型和智能化升级提供了有力支持。本文将对工业网关的功能与作用进行解…

深入理解PHP命名空间

在PHP项目中&#xff0c;命名空间&#xff08;namespace&#xff09;是一个非常重要的特性。它不仅帮助开发者组织代码&#xff0c;还能避免类、函数、常量等命名冲突问题。本文将详细介绍PHP命名空间的概念、使用方法和最佳实践。 一、什么是命名空间&#xff1f; 命名空间…

【PyQt5】一文向您详细介绍 setContentsMargins() 的作用

【PyQt5】一文向您详细介绍 setContentsMargins() 的作用 下滑即可查看博客内容 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff1a;985高校的普通…

EWM学习之旅-1-EWM100

系统学习一个业务模块已经变得越来越重要&#xff0c;开始吧&#xff0c;EWM&#xff01; EWM的Learning Journey中包括7本 ebook,100/110/115/120/125/130/140&#xff0c;一本一本的啃吧&#xff0c;相信很多内容是重复的。 EWM100很适合初学者&#xff0c;了解概念术语&…

charles破解

一、Charles官网下载安装包二、安装charles三、charles破解 一、Charles官网下载安装包 根据自己电脑系统 官网下载即可。 链接: https://www.charlesproxy.com/download/latest-release/ 二、安装charles 点击下载的安装包&#xff0c;然后进行安装。 三、charles破解 打…

[解决方案]使用微软拼音打中文卡顿到离谱

去这里看&#xff0c;发现有65535个文件&#xff0c;基本都是临时文件。删除后测试了一下&#xff0c;不会卡顿了但是只要打中文还是会疯狂生成tmp临时文件。 问题&#xff1a;输入法不兼容 解决方案 先把上面那个文件夹里的tmp文件全删了 直接点是&#xff0c;其他的文件会…

BEVM基于OP-Stack发布首个以WBTC为GAS连接以太坊和比特币生态的中继链

为了更好的连接以太坊和比特币生态&#xff0c;BEVM团队正在基于OPtimism的OP Stack来构建一个以WBTC为GAS兼容OP-Rollup的中继链&#xff0c;这条中继链将作为一种完全去中心化的中间层&#xff0c;把以太坊上的主流资产(WBTC/ ETH/USDC/USDT等)引入到BEVM网络。 不仅如此&am…