【算法练习Day18】二叉搜索树的最小绝对差二叉搜索树中的众数 二叉树的最近公共祖先

news2025/9/20 12:44:43

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:练题
🎯长路漫漫浩浩,万事皆有期待

文章目录

  • 二叉搜索树的最小绝对差
  • 二叉搜索树中的众数
  • 二叉树的最近公共祖先
  • 总结:

二叉搜索树的最小绝对差

530. 二叉搜索树的最小绝对差 - 力扣(LeetCode)

这道题要使用先处理底部节点的方法,搜索树的遍历解法通常都是使用中序遍历来解出答案。

思路就是按照搜索树的特性:中间节点一定比左子树部分节点数值大,我们让一个指针指向该节点的上一个位置,然后用我们当前的节点值减去上一个节点的值,用一个变量保存最小值,最后递归完毕返回。这是双指针的解法。变量创建一个大数,每次都和这个数比较比它小就和它交换即可,但是这种思路有一个弊端,就是当二叉树的两个节点相减如果本来就非常大,可能会引发一些bug。

class Solution {
public:
    int result=INT_MAX;
    TreeNode* pre=nullptr;
    void traversal(TreeNode* cur)
    {
        if(cur==nullptr)
        {
            return;
        }
        traversal(cur->left);
        if(pre!=nullptr)
        {
            result=min(result,cur->val-pre->val);
        }
        pre=cur;
        traversal(cur->right);
    }
    int getMinimumDifference(TreeNode* root) {
        traversal(root);
        return result;
    }
};

为了避免这种bug,我们可以将最后返回的变量result的值开始用第一次减出来的值,接下来每次减出来的值都和它做对比,这样无论两个数减出来的值有多大也不会出现bug(但是承接该数的数据类型也有可能会溢出)。当然这道题我们同样也可以使用中序遍历存数组的方法,然后比较数组中各元素相减求最小值。

二叉搜索树中的众数

501. 二叉搜索树中的众数 - 力扣(LeetCode)

先说一说常规做法,遍历一次二叉树,用map来存储每一个数出现的频率,然后再用数组来承接,将数组按照频率的高低来排序,最终输出答案,注意可能有多个众数,比如说有两个数出现的频率都是最高的,那么将它们都返回来,这时我们如果数组是从频率大到小,那么我们就返回第一个数,然后比较它后面有没有和它频率相等的,如果有也一并加入返回。

class Solution {
public:

    void searchBST(TreeNode* cur,unordered_map<int,int>&map)
    {
        if(cur==nullptr)
        {
            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;
    }
    vector<int> findMode(TreeNode* root) {
        unordered_map<int,int>map;
        vector<int> result;
        if(root==nullptr)
        {
            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++)
        {
            if(vec[i].second==vec[0].second)
            {
                result.push_back(vec[i].first);
                
            }
            else
            {
                break;
            }
        }
        return result;
    }
};

这就是第一种常规做法,需要遍历两次二叉树。

但是我们可以遍历一次二叉树就完成题目需求。思路是:仍然是中序遍历,我们设立两个变量一个是当前数字的出现频率,另一个是我们在遍历过程中出现的最大频率有多少,最大频率我们一开始是无法确定的,所以它是实时更新的,而结果数组也是实时更新的,那么我们怎么知道一个数出现了多少次呢?还是用双指针,一个指向该节点上一个节点,另一个指向当前节点,如果两个节点值相等那么说明此时有两个一样的值的节点

class Solution {
public:
    vector<int> result;
    TreeNode* pre=nullptr;
    int maxcount=0,count=1;
    void searchBST(TreeNode* cur)
    {
        if(cur==nullptr)
        {
            return;
        }
        searchBST(cur->left);
        if(pre==nullptr)
        {
            count=1;
        }
        else if(pre->val==cur->val)
        {
            count++;
        }
        else
        {
            count=1;
        }
        pre=cur;

        if(count==maxcount)
        {
            result.push_back(cur->val);
        }

        if(count>maxcount)
        {
            maxcount=count;
            result.clear();
            result.push_back(cur->val);
        }

        searchBST(cur->right);
        return;
    }
    vector<int> findMode(TreeNode* root) {
        count=0;
        maxcount=0;
        pre=nullptr;
        result.clear();

        searchBST(root);
        return result;
    }
};

代码核心在于递归中间部分,如果我们遍历时发现当前该值的出现频率和最大出现频率相等,那么直接加入进结果集合,如果比当前最大出现频率还大,清空数组并加入当前节点值。

二叉树的最近公共祖先

236. 二叉树的最近公共祖先 - 力扣(LeetCode)

一道略有难度的题,在于它的思路也在于对递归的理解。

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

代码整体看上去不长,思路是首先我们要知道什么时候返回节点,也就是结束递归逻辑如何书写,这里我们是遍历到空直接返回到上一层,这一点无需多言,其次我们找到p,q目标节点之一也要向上一级返回,这是为了告诉上一层我们找到了p或者q其中一个将它存在left或者right层次里,然后left有值后接着递归寻找right。

寻找p,q的最近祖先节点,有两种情况,其一是pq在两侧,也就是最常见的情况最容易被想到的情况,这样的话我们在寻找到left和right之后把返回到上一层的root节点直接返回上去,那如果暂时还没有找到另一个呢?我们怎么告诉上一层它的左侧或者右侧找到了其中一个呢?我们在left&&right的后面还有两个if来判断,告诉它我们找到了其一,当然找到其一我们并不在代码中具体表现找到哪一个,只是告诉找到了,且pq一定会被找到,因为题目已经说过了,一定存在pq。两个一起找到后返回一次root也就是中间节点处理的第一个if逻辑,然后我们通过返回左子树或右子树进入第二个或者第三个if完成向上返回。

那么第二种情况是什么呢?就是p或者q充当最近祖先节点的时候,其实这种情况也在代码里面体现了,由于p或者q在一条路径上所以我们遇到了最上面的p或者q直接返回来了,也就找到了最近祖先节点。

总结:

今天我们完成了二叉搜索树的最小绝对差、二叉搜索树中的众数、 二叉树的最近公共祖先三道题,相关的思想需要多复习回顾。接下来,我们继续进行算法练习。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

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

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

相关文章

k8s相关的概念

1.1 K8S YAML文件详解 K8S Yaml 配置文件主要分为&#xff1a;基本标签、元数据标签、资源内容 三个部分&#xff0c;要想对K8S熟练的掌握&#xff0c;必须要了解YAML配置文件中常见的参数和指令的含义。 1&#xff09;基本标签主要是在文件起始位置&#xff0c;例如&#xff…

基于JAVA+SpringBoot+Vue的前后端分离的公益慈善服务平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着网络技术的发展&a…

2023年中国企业营销数字化行业发展趋势分析:企业营销数字化花费增速放缓[图]

随着通信设施和移动互联网的高速发展&#xff0c;中国MarTech市场也面临着一些挑战&#xff0c;在企业数字化转型的浪潮中&#xff0c;通过供需双方共同发力、技术能力不断升级和市场宏观环境的共同加持&#xff0c;助力中国企业营销数字化的发展。 中国企业营销数字化发展脉络…

postman介绍和安装,发送带参数的GET请求(超详细~)

postman的介绍和安装 Postman的介绍 Postman 是一款谷歌开发的接口测试工具,使API的调试与测试更加便捷。 它提供功能强大的 Web API & HTTP 请求调试。它能够发送任何类型的HTTP 请求 (GET, HEAD, POST, PUT..)&#xff0c;附带任何数量的参数 headers。 postman是一款…

Docker快速上手:使用Docker部署Drupal并实现公网访问

文章目录 前言1. Docker安装Drupal2. 本地局域网访问3 . Linux 安装cpolar4. 配置Drupal公网访问地址5. 公网远程访问Drupal6. 固定Drupal 公网地址 前言 Dupal是一个强大的CMS&#xff0c;适用于各种不同的网站项目&#xff0c;从小型个人博客到大型企业级门户网站。它的学习…

视频编解码(七)之FOURCC和YUV关系简介

FOURCC是4字节代码&#xff0c;是一个codec中对压缩格式、颜色、像素格式等的标识。按一个字节8bit&#xff0c;FOURCC通常占4字节32bit。 FOURCC is short for “four character code” - an identifier for a video codec, compression format, color or pixel format used i…

1600*C. Circle of Monsters(贪心)

Problem - 1334C - Codeforces 解析&#xff1a; 对于某个怪兽&#xff0c;他的耗费为两种情况&#xff0c;要么直接用子弹打&#xff0c;要么被前面的怪兽炸&#xff0c;显然第二种情况耗费更少。 统计出所有怪兽的 max&#xff08;0&#xff0c;a[ i ] - b[ i - 1 ]&#xff…

一句话代码富集分析gost ghost

1.5 ##富集分析---------- #BiocManager::install("gprofiler2") library(gprofiler2) ## We can perform an enrichment analyses with the genes in the complex EnrichmentResults <- gprofiler2::gost(genes_complex, significant TRUE,user_threshold 0.00…

CTF/AWD竞赛标准参考书+实战指南:《AWD特训营》

作者简介&#xff1a; 辭七七&#xff0c;目前大二&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; 七七的闲谈 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f…

Android JNI代码语法解释

文章目录 JNI中的JNIEXPORT、JNIIMPORT和JNICALLJVM如何查找native方法①按照JNI规范的命名规则②调用JNI提供的RegsterNatives函数&#xff0c;将本地函数注册到JVM中示例代码 JNI数据类型JNI字符串的处理①获取字符串②释放字符串③创建字符串④其他字符串处理API JNI中的JNI…

阿里云李腾飞:基于ECS倚天实例的大数据加速最佳实践

云布道师 为了更好地方便各位开发者和用户了解并应用 ECS 倚天实例&#xff0c;由阿里云弹性计算联合基础软件团队 & 平头哥 & 安谋科技&#xff08;arm&#xff09;&#xff0c;共同发起了【倚天实例迁移课程】&#xff0c;本系列课程共计 10 节课程&#xff0c;共分为…

C++学习day6

1.思维导图 2.作业&#xff1a; 编程题&#xff1a; 以下是一个简单的比喻&#xff0c;将多态概念与生活中的实际情况相联系&#xff1a; 比喻&#xff1a;动物园的讲解员和动物表演 想象一下你去了一家动物园&#xff0c;看到了许多不同种类的动物&#xff0c;如狮子、大象…

云原生Kubernetes:K8S集群版本升级(v1.20.6 - v1.20.15)

目录 一、理论 1.K8S集群升级 2.集群概况 3.升级集群 4.验证集群 二、实验 1.升级集群 2.验证集群 三、问题 1.给node1节点打污点报错 一、理论 1.K8S集群升级 &#xff08;1&#xff09;概念 搭建K8S集群的方式有很多种&#xff0c;比如二进制&#xff0c;kubeadm…

Outlook导入导出功能灰色,怎么解决

下载安装 Outlook 软件后&#xff0c;登陆账号&#xff0c;然后选择“文件” - “导出”&#xff0c;结果发现“导出”按钮是灰色的&#xff0c;根本无法导出。根据官方说法&#xff1a;由于配置没有完成或者office产品没有正确激活。outlook导出键为灰色原因由于配置没有完成或…

第五篇Android--EditText详解

EditText 字面意思可以编辑的文本。在Android中就是用来接收用户输入的输入框。 1.基本用法 <EditTextandroid:id"id/id_phone_edit"android:layout_width"match_parent"android:layout_height"48dp"android:background"android:color/…

大数据精准营销是从几个维度帮您去筛选准客户?

人工智能和大数据精准营销的存在则可以准确捕捉到消费者最近的心理活动预期&#xff0c;可以根据消费者心理活动准确告诉他&#xff0c;他需要的信息在哪里。由于每个人看到的效果不同&#xff0c;消费者会感觉广告是为他量身打造的。这也就是我们所说的精准营销。 而精准营销…

Elasticsearch 和 Arduino:一起变得更好!

作者&#xff1a;Enrico Zimuel 使用 Arduino IoT 设备与 Elasticsearch 和 Elastic Cloud 进行通信的简单方法 在 Elastic&#xff0c;我们不断寻找简化搜索体验的新方法&#xff0c;并开始关注物联网世界。 来自物联网的数据收集可能非常具有挑战性&#xff0c;尤其是当我们…

【面试经典150 | 哈希表】字母异位词分组

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;排序哈希表方法二&#xff1a;数组作为哈希表的键方法三&#xff1a;字符串作为哈希表的键知识回顾accumulate 写在最后 Tag 【自定义哈希】【哈希表】【数组】 题目来源 49. 字母异位词分组 题目解读 将字符串数组中…

面试全攻略:ElasticSearch分页与MySQL分页的底层逻辑与优化技巧

大家好&#xff0c;我是小米&#xff01;今天&#xff0c;我要和大家一起深入探讨一个在技术面试中经常被问到的问题&#xff1a;ElasticSearch中的分页与MySQL中的分页有什么区别&#xff1f;分页是数据库查询中非常常见的操作&#xff0c;但当我们在不同的数据库中执行分页操…

画面清晰如真:OLED透明拼接屏在金华市的画质表现

金华市位于中国浙江省中西部&#xff0c;是中国重要的历史文化名城之一。 金华市拥有悠久的历史和丰富的文化遗产&#xff0c;如古城墙、古建筑和古镇等。 这为OLED透明拼接屏技术的应用提供了丰富的创作素材和展示主题。 金华市的著名景点 义乌国际商贸城&#xff1a;义乌国…