【算法训练 day23 二叉搜索树的最小绝对差、二叉搜索树的众数、二叉树的最近公共祖先】

目录

  • 一、二叉搜索树的最小绝对差-LeetCode 530
    • 思路
    • 实现代码
      • 递归处理
      • 使用数组
    • 个人问题
  • 二、二叉搜索树的众数-LeetCode 501
    • 思路
    • 实现代码
      • map统计计数
      • 递归过程中计数
    • 个人问题
  • 三.二叉树的最近公共祖先-LeeCode 236
    • 思路
    • 实现代码
    • 个人问题
    • 总结


一、二叉搜索树的最小绝对差-LeetCode 530

Leecode链接: leetcode 977
文章链接: 代码随想录
视频链接: B站

给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。

示例:

输入:root = [4,2,6,1,3]
输出:1

思路

解法1:转化为数组,然后逐个计算差值,返回最小差值即可。解法2:由于题目是搜索树,所以差值最小必定出现在相邻节点,使用全局变量保存上一个节点,中间节点计算差值并保存可能的最小差值。

实现代码

递归处理

//cpp
class Solution {
public:TreeNode* pre = nullptr;int minnum = INT32_MAX;void test(TreeNode* root){if(root == nullptr) return;test(root->left);if(pre != nullptr){minnum = min(minnum,root->val - pre->val);}pre = root;test(root->right);}int getMinimumDifference(TreeNode* root) {test(root);return minnum;}
};

使用数组

//cpp
class Solution {
private:
vector<int> vec;
void traversal(TreeNode* root) {if (root == NULL) return;traversal(root->left);vec.push_back(root->val); // 将二叉搜索树转换为有序数组traversal(root->right);
}
public:int getMinimumDifference(TreeNode* root) {vec.clear();traversal(root);if (vec.size() < 2) return 0;int result = INT_MAX;for (int i = 1; i < vec.size(); i++) { // 统计有序数组的最小差值result = min(result, vec[i] - vec[i-1]);}return result;}
};

个人问题

对于使用双指针还不够熟练。


二、二叉搜索树的众数-LeetCode 501

Leecode链接: LeetCode 501
文章链接: 代码随想录
视频链接: B站

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。

如果树中有不止一个众数,可以按 任意顺序 返回。

示例:

输入:root = [1,null,2,2]
输出:[2]

思路

两种解法:1.中序遍历形成map数组,然后对数组进行排序,可得众数。2.递归过程中计算众数,使用一个计数器,每遇到相同的值count加1,遇到不同的值count恢复为1,然后使用maxcount记录可能成为众数出现的频率。遍历完整个树为止。

实现代码

map统计计数

//cpp
class Solution {
private:void searchBST(TreeNode* cur, unordered_map<int, int>& map) { // 前序遍历if (cur == NULL) return ;map[cur->val]++; // 统计元素频率searchBST(cur->left, map);searchBST(cur->right, map);return ;
}
bool static cmp (const pair<int, int>& a, const pair<int, int>& b) {return a.second > b.second;
}
public:vector<int> findMode(TreeNode* root) {unordered_map<int, int> map; // key:元素,value:出现频率vector<int> result;if (root == NULL) return result;searchBST(root, map);vector<pair<int, int>> vec(map.begin(), map.end());sort(vec.begin(), vec.end(), cmp); // 给频率排个序result.push_back(vec[0].first);for (int i = 1; i < vec.size(); i++) {// 取最高的放到result数组中if (vec[i].second == vec[0].second) result.push_back(vec[i].first);else break;}return result;}
};

递归过程中计数

//cpp
class Solution {
public:int count = 0;int maxcount = 0;vector<int> res;TreeNode* pre = nullptr;void test(TreeNode* root){if(root == nullptr){return;}test(root->left);if(pre == nullptr){count = 1;}else if(root->val == pre->val){count++;}else{count = 1;}if(count>maxcount){maxcount = count;res.clear();res.push_back(root->val);}else if(count == maxcount){res.push_back(root->val);}pre = root;test(root->right);return;}vector<int> findMode(TreeNode* root) {res.clear();test(root);return res;}
};

个人问题

在实现代码时,maxcount的更新位置写在了root->val != pre->val的条件分支中,导致没有存储真正的众数;count初始值最初个人设置为1,但在执行时出现访问未定义行为,原因在于count初始值手动设置为1,但pre初始值也为1,导致不能访问正确的第一个元素的值。


三.二叉树的最近公共祖先-LeeCode 236

Leecode链接: LeetCode 236
文章链接: 代码随想录
视频链接: B站

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

示例:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3

思路

使用后序遍历,考虑一个一般情况,两个节点为某个父节点的左右子树,如果找到了该节点左右子树的递归函数就返回该节点的指针给父节点的这一层函数,这一层根据返回结果返回对应指针,如果都存在,表明要找的节点就在该父节点的孩子节点中,返回父节点自身即可。考虑一个特殊情况,如果两个节点互为父子节点,这时直接返回最先遇到的节点指针即可,如果一侧为空返回另一侧不为空的节点指针。

实现代码

//cpp
class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(root == NULL) return NULL;if(root->val==p->val||root->val==q->val)return root;TreeNode* left_p = lowestCommonAncestor(root->left,p,q);TreeNode* right_p = lowestCommonAncestor(root->right,p,q);if(left_p&&right_p)return root;else if(!left_p&&right_p) return right_p;else if(left_p&&!right_p) return left_p;else return NULL;}
};

个人问题

代码没有自己写出来。

总结

本题比较巧妙,对各个情况处理比较特殊。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【退役之重学Java】如何处理消息丢失问题

即如何保证消息的可靠性传输 一、场景 网络丢包&#xff0c;导致丢失消息RabbitMQ 没来得及保存消息&#xff0c;就挂掉了消费者接受到消息&#xff0c;但没处理完&#xff0c;消费者挂掉了 二、怎么办 生产者 将 channel 设置为 confirm 模式&#xff0c;是异步模式&#x…

Linux-笔记 Makefile简单入门

1、Makefile Makefile是一种文本文件&#xff0c;通常用于定义项目的编译规则和依赖关系。它通常与GNU Make工具一起使用&#xff0c;用于自动化软件项目的构建过程。Makefile中包含了一系列规则&#xff0c;每个规则定义了如何生成一个或多个目标文件以及生成这些目标文件所需…

Baidu Comate智能编码助手

Baidu Comate智能编码助手 &#x1f388;1.Baidu Comate的简介&#x1f388;2.安装Baidu Comate&#x1f388;3.Baidu Comate实现功能&#x1f388;4.使用注释进行智能代码提示&#x1f388;5.结束语 &#x1f388;1.Baidu Comate的简介 根据官网的介绍&#xff0c;我们了解到B…

作为一名软件开发,您是否认同“如果代码有效,就不要修复它”这一理论?

请大家关注我的公众号&#xff0c;“老胡聊Java” 这句话非常有道理&#xff0c;因为这句话不仅包含了技术&#xff0c;而且还包含了人情世故。 1 一个项目的代码动辄几千几万行&#xff0c;而且分布的位置也不同&#xff0c;比如有java代码python代码&#xff0c;甚至还可能有…

力扣每日一题113:路径总和||

题目 中等 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSu…

《深入理解kafka》对于实际问题的理解

Q1&#xff1a;消息可靠性(不重不漏) 1.1 如何保证消息不丢 1.2 如何保证消息不重 Q2&#xff1a;积压/消费能力 2.1 线上积压排查思路 2.2 增加消费能力 Q1&#xff1a;消息可靠性(不重不漏) 理解可靠性前。介绍消息语义&#xff0c;即消息传递的标准 标准 丢失 重复 适用…

Redis-3 数据持久化

一.什么是数据持久化&#xff1f; redis是把数据存储在内存中的&#xff0c;而采用DRAM芯片存储的内存会面临断电导致数据丢失的问题&#xff0c;因此我们可以将redis在内存中的数据存储一份到磁盘中&#xff0c;用于内存数据丢失时的恢复&#xff0c;这个过程就叫做数据持久化…

完成单位投稿任务找投稿渠道不用精选10个1个就够了

在单位担任信息宣传员的这几年,我深刻体会到了“笔耕不辍”的艰辛与挑战。起初,面对单位的宣传需求,我遵循传统的投稿路径,即通过电子邮件的方式,一家接一家地向各大媒体投递稿件。那时的我,以为只要稿件质量上乘,自然能够获得青睐,却未曾料到,这是一条漫长而曲折的道路。 邮箱…

算法day03

第一题 179. 查找总价格为目标值的两个商品 本题采用前后指针和单调性规律可解&#xff1b; 解题思路如下&#xff1a; 1、设置前后指针 2、前后指针所指的两数之和大于目标数&#xff0c;右指针左移&#xff1b; 前后指针所指的两数之和小于目标数&#xff0c;左指针右移&…

“视频剪辑新境界:批量高效处理,画面虚化与播放速度调整一气呵成!“

在视频制作的广阔天地中&#xff0c;剪辑是赋予作品生命的关键环节。然而&#xff0c;面对大量的视频素材&#xff0c;如何高效地进行剪辑、调整&#xff0c;使每一帧画面都充满魅力&#xff0c;成为许多创作者面临的挑战。今天&#xff0c;我们为您带来一款颠覆性的视频剪辑工…

学习笔记:【QC】Android Q - IMS 模块

一、IMS init 流程图 高清的流程图参考&#xff1a;【高清图&#xff0c;保存后可以放大看】 二、IMS turnon 流程图 高清的流程图参考&#xff1a;【高清图&#xff0c;保存后可以放大看】 三、分析说明 1、nv702870 不创建ims apn pdp 2、nv702811 nv702811的时候才创建…

Objective-C的对象复制与拷贝选项

对象复制与拷贝 文章目录 对象复制与拷贝copy与mutablecopycopy与mutablecopy的简介示例&#xff1a;不可变对象的复制可变对象的复制 NSCopying和NSMutableCopying协议深复刻和浅复刻浅拷贝&#xff08;Shallow Copy&#xff09;&#xff1a;深拷贝&#xff08;Deep Copy&…

同步电机原理解析

同步电机 同步带年纪&#xff0c;顾名思义无论负载如何&#xff0c;都能以恒定的速度运转&#xff0c;它以高效率著称 这种恒速特性是通过恒定磁场和旋转磁场的相互作用实现的&#xff0c;与其他电机一样&#xff0c;同步电机由定子和转子组成&#xff0c;定子铁芯由硅片层叠而…

无人直播需要什么软件系统?最新AI实景自动无人直播软件:智能化引领直播拓客新时代

随着互联网的快速发展&#xff08;无人直播招商加盟&#xff1a;hzzxar&#xff09;直播行业已经成为商家品牌推广和商品销售的热门方式。近年来&#xff0c;人工智能技术的飞速发展&#xff0c;催生了一款令人惊叹的AI实景自动无人直播软件&#xff0c;为商家提供了全新的直播…

修改表空间的状态

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 表空间有4种状态:联机、脱机、只读和读写。修改其中某一种状态的语句如下所示 设置表空间 tspace 为联机状态。 SQL>ALTER TABLESPACE space ONLINE: 设置表空间 tspa…

Node.js身份证实名认证接口、身份证识别API

翔云OCR身份证查验集合了身份证号核验&#xff0c;身份信息核验&#xff0c;身份核验。 基于翔云身份证识别接口的Node.js开发示例代码如下&#xff1a; var request require(request); var options {method: POST,url: https://netocr.com/api/recogliu.do,headers: {},fo…

google地图js,添加标记,以及infowindow信息弹窗

&#xff08;谷歌地图版本V3&#xff09; var contentString "<div classdevinfo><P>设备ID: BJ-20240507</p> <P>设备状态: 正常</p> <P>通讯信号: 89% </p> <P>设备位置: 中国</p> <P>剂量率: 988</p&…

鸿蒙开发接口Ability框架:【(StaticSubscriberExtensionAbility)】

StaticSubscriberExtensionAbility StaticSubscriberExtensionAbility模块提供静态订阅者扩展能力的类别的能力。 说明&#xff1a; 本模块首批接口从API version 9 开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 本模块接口仅可在Stage模型下…

SpringBoot之Zuul服务

概述 Spring Cloud Netflix zuul组件是微服务架构中的网关组件,Zuul作为统一网关,是所有访问该平台的请求入口,核心功能是路由和过滤。 目前公司业务就是基于Zuul搭建的网关服务,且提供的服务包括转发请求(路由)、黑名单IP访问拦截、URL资源访问时的权限拦截、统一访问日志记…

【退役之重学Java】如何保证从消息队列里拿到的消息顺序执行

一、场景 MySQL binlog 同步数据&#xff0c;比如大数据team。在MySQL中进行增删改查&#xff0c;将其 binlog 发送到 MQ 里面&#xff0c;到消费出来执行&#xff0c;这里就必须要保证其顺序执行&#xff0c;不然数据库就会错乱。 二、如何保证消息的顺序性呢&#xff1f; …