代码随想录算法训练营day20

news2025/7/10 18:12:18

题目:530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

参考链接:代码随想录

530.二叉搜索树的最小绝对差

思路:我一开始想到的方法是先生成中序序列,然后对相邻两项的差进行计算,取最小值,时间复杂度O(n)。

class Solution {
public:
    vector<int> inorder;
    void traverse(TreeNode* root){
        if(!root){
            return;
        }
        traverse(root->left);
        inorder.push_back(root->val);
        traverse(root->right);
    }
    int getMinimumDifference(TreeNode* root) {
        traverse(root);
        //节点范围从2开始
        int min=INT_MAX;
        for(int i=1;i<inorder.size();i++){
            if(inorder[i]-inorder[i-1]<min){
                min=inorder[i]-inorder[i-1];
            }
        }
        return min;
    }
};

然后想想能不能直接迭代,即每次遍历的时候记录前置节点,然后将差值对比。

class Solution {
public:
    TreeNode* pre=nullptr;
    int getMinimumDifference(TreeNode* root) {
        if(!root){
            return INT_MAX;//指示最小差值不存在
        }
        int left=getMinimumDifference(root->left);
        int min=left;//首先设置为左子树算出的结果
        if(pre&&root->val-pre->val<left){
            min=root->val-pre->val;

        }
        pre=root;//赋值前置节点,然后继续往后遍历
        int right=getMinimumDifference(root->right);
        if(right<min){//完成了左右中的比较
            min=right;
        }
        return min;
    }
};

实际上这样写代码很容易出错,真正写的时候就可以用额外生成的vector。标答把答案当做全局变量了,我们也建议单独写一个void遍历函数
标答:

class Solution {
private:
int result = INT_MAX;
TreeNode* pre = NULL;
void traversal(TreeNode* cur) {
    if (cur == NULL) return;
    traversal(cur->left);   // 左
    if (pre != NULL){       // 中
        result = min(result, cur->val - pre->val);
    }
    pre = cur; // 记录前一个
    traversal(cur->right);  // 右
}
public:
    int getMinimumDifference(TreeNode* root) {
        traversal(root);
        return result;
    }
};

迭代法pass。

501.二叉搜索树中的众数

思路:简单的想法就是生成中序数组,然后使用哈希表统计元素出现个数,然后再输出。但是会有很多额外空间。其实这个方法对不是BST也可以,就是记录所有元素个数。时间复杂度O(n)。

class Solution {
public:
    unordered_map<int,int> mp;
    void traverse(TreeNode* root){
        if(!root){
            return;
        }
        traverse(root->left);
        mp[root->val]++;
        traverse(root->right);
    }
    vector<int> findMode(TreeNode* root) {
        vector<int> ans;
        int max=0;
        traverse(root);
        for(auto it:mp){
            if(it.second>max){
                max=it.second;
            }
        }
        for(auto it:mp){
            if(it.second==max){
                ans.push_back(it.first);
            }
        }
        return ans;
    }
};

标答将map进行了一个转换为vector后排序,我觉得没必要,这样复杂度反而变成O(nlogn)。

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;
    }
};

考虑一下能不能利用BST的性质。即中序遍历有序,可以直接再遍历过程中操作,和上一题一样,不需要使用额外空间,使用pre指针,在对每个节点遍历的时候记录其出现次数,遍历一遍即可记录最大次数,然后第二次遍历,对最大次数的节点进行输出即为结果。看完解析发现可以通过一些简单的代码操作只进行一次遍历,即每次进行次数更新的时候,将结果clear()即可。可以看到对BST,利用其有序性,双指针有很大用处

class Solution {
public:
    TreeNode* pre=nullptr;
    int count=0;
    int maxCount=INT_MIN;
    void traverse(TreeNode* root,vector<int>& ans){
        if(!root){
            return;
        }
        traverse(root->left,ans);
        if(!pre||root->val!=pre->val){//第一个元素,指针为空,或者当前和pre不同
            count=1;
        }
        else{//两个相邻相等
            count++;
        }
        pre=root;
        //此时已经完成count计数,然后和max比较
        if(count>maxCount){
            ans.clear();//更新,之前全部删掉
            maxCount=count;
            ans.push_back(root->val);
        }
        else if(count==maxCount){//等于也要增加结果
            ans.push_back(root->val);
        }
        traverse(root->right,ans);
    }
    vector<int> findMode(TreeNode* root) {
        vector<int> ans;
        traverse(root,ans);
        return ans;
    }
};

迭代法pass

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

思路:由于二叉树无法自底向上搜索,肯定需要回溯法。给定pq,需要分情况讨论。首先是简单情况,一个节点的两个孩子分别为p和q,这时候直接返回p或者q,如果为空,则返回空。我们需要把返回值一层一层往上传递,对根节点root,如果左右孩子都为空,则返回空,如果两个节点仅有一个找到了 ,则直接把这一个往上传递,如果两个都不为空,那么这个节点就是最近公共祖先,直接往上返回,最后的返回结果会传递到根节点。本题需要先处理左右孩子,最后确定根节点的返回值,为后序遍历。时间复杂度O(n)。
在这里插入图片描述

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root||root==p||root==q){//终止条件,表示找到
            return root;
        }
        TreeNode* left=lowestCommonAncestor(root->left,p,q);
        TreeNode* right=lowestCommonAncestor(root->right,p,q);
        if(!left&&!right){//处理完左右后四种情况
            return nullptr;
        }
        else if(left&&!right){
            return left;
        }
        else if(!left&&right){
            return right;
        }
        else{
            return root;
        }
    }
};

没有迭代法。

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

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

相关文章

代码随想录刷题笔记-Day21

1. 二叉搜索树中的插入操作 701. 二叉搜索树中的插入操作https://leetcode.cn/problems/insert-into-a-binary-search-tree/给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。…

聊聊 Git SubModule(子模块)

比如在公司不同开发团队中&#xff0c;有一个基础共享库&#xff0c;同时被多个项目调用。若要保证基础共享库的动态更新&#xff0c;那么就需要把共享库独立为一个代码库&#xff0c;但是分别把共享库中的文件拷贝到各自的项目中会造成冗余&#xff0c;而且再次更新共享库就会…

提升认知水平和防止偏见浅谈

提升认知水平和防止偏见浅谈 《庄子外物》&#xff1a;井蛙不可语海&#xff0c;夏虫不可语冰。 不要跟井底的青蛙谈论大海&#xff0c;因为它的认知只有井底那么大&#xff0c;大海对于它来说是认知盲区&#xff1b;不要与夏虫去谈论冰雪&#xff0c;因为夏虫一生很短没有经历…

香港优才计划认可大学名单有哪些?武大/西安交大/哈工大/中南大学毕业生,能加名校30分吗?

关注香港优才的朋友应该知道&#xff0c;优才计划采用计分制&#xff0c;综合计分制下&#xff0c;有一个“名校”加分项&#xff0c;如果毕业院校在世界百强大学名单内&#xff0c;可以多加30分&#xff01; 但这个世界百强大学名单&#xff0c;可能有很多人不是很清楚&#x…

用冒泡排序实现快速排序(qsort函数),指针进阶实例

目录 1、qsort函数是什么 2、冒泡排序实现指针进阶 2.1 主函数 2.2 功能函数声明​编辑 2.3 my_qsort函数介绍 2.4 Swap函数 总结 1、qsort函数是什么 qsort函数是c语言自带的函数&#xff0c;其功能是实现快速排序。我们来看一下他的参数和返回值&#xff1a; 以上就是q…

代码随想录算法训练营DAY21 | 二叉树 (9)

一、LeetCode 669 修建二叉搜索树 题目链接&#xff1a;669.修建二叉搜索树https://leetcode.cn/problems/trim-a-binary-search-tree/description/ 思路&#xff1a;递归三部曲-定参数、返回值-定终止条件-定单层递归逻辑 class Solution {public TreeNode trimBST(TreeNode …

深度学习基础——卷积神经网络(一)

卷积操作与自定义算子开发 卷积是卷积神经网络中的基本操作&#xff0c;对于图像的特征提取有着关键的作用&#xff0c;本文首先介绍卷积的基本原理与作用&#xff0c;然后通过编写程序实现卷积操作&#xff0c;并展示了均值、高斯与sobel等几种经典卷积核的卷积效果&#xff…

HTML-介绍-MDN文档学习笔记

HTML-介绍 查看更多学习笔记&#xff1a;GitHub&#xff1a;LoveEmiliaForever MDN中文官网 HTML-简介 MDN 文档引用&#xff1a; 就其核心而言&#xff0c;HTML 是一种相当简单的、由不同元素组成的标记语言&#xff0c;它可以被应用于文本片段&#xff0c;使文本在文档中具…

Security6.2 中的SpEL 表达式应用(权限注解使用)

最近学习若依框架&#xff0c;里面的权限注解涉及到了SpEL表达式 PreAuthorize("ss.hasPermi(system:user:list)")&#xff0c;若依项目中用的是自己写的方法进行权限处理&#xff0c; 也可以只用security 来实现权限逻辑代码&#xff0c;下面写如何用security 实现。…

[计算机网络]---UDP协议

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、端口号…

HarmonyOS - 实现多设备协同开发实战教程~

前言 现在随着个人设备越来越多&#xff0c;越来越需要多个设备之间相互感知和连接&#xff0c;设备和设备之间可以相互联动&#xff0c;形成互联互通的场景&#xff0c;而搭载HarmonyOS的设备恰好可以满足这一点 。下面通过开发一个HarmonyOS的多端分布式表白应用来实现设备之…

STM32_ESP8266 连接阿里云 操作图解

一、烧录MQTT固件 ESP8266出厂时&#xff0c;默认是&#xff1a;AT固件。连接阿里云需要&#xff1a;MQTT固件。 因此&#xff0c;我们需要给8266重新烧录 MQTT固件。 针对“魔女开发板&#xff0c;ESP8266模块烧录MQTT固件&#xff0c;图解教程如下&#xff1a; ESP8266 烧录 …

代码随想录算法训练营|二叉树总结

二叉树的定义&#xff1a; struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode():val(0),left(nullptr),right(nullptr){}TreeNode(int val):val(val),left(nullptr),right(nullptr){}TreeNode(int val,TreeNode* left,TreeNode* right):val(val),left(left),…

网工内推 | 证券公司急招网工,base上海,年薪50W

01 广发证券 招聘岗位&#xff1a;网络工程师 任职要求&#xff1a; 1、懂基础建设网络&#xff0c;虚拟化&#xff0c;或者服务器中任意一个都可以&#xff08;需资深&#xff09;2、985/211本硕 3、年龄最好35以下 薪资待遇&#xff1a; 1、工作时间9:00-17:00 2、根据资历…

思腾合力邀您共赴第二届世界元宇宙大会

由中国仿真学会、中国指挥与控制学会和北京理工大学共同主办&#xff0c;上海市嘉定区安亭镇人民政府和中国仿真学会元宇宙专业委员会承办的第二届世界元宇宙大会大会以“虚实相生、产业赋能”为主题&#xff0c;聚焦元宇宙关键技术发展的共性问题&#xff0c;交流元宇宙技术产…

Window系统GPT-SoVITS配置安装

GPT-SoVITS配置安装 GPT-SoVITS配置Python下载以及安装源文件安装依赖 运行整理在安装配置环境时遇到的报错总结 GPT-SoVITS配置 作者链接 Python下载以及安装 版本这里根据教程的版本走即可&#xff0c;这里不会安装python或者不会配置环境的参考我之前的文章 Python 3.9,…

C# GTS四轴运动控制器实例(固高科技步进电机不带编码器)

注&#xff1a;由于电机不带编码器&#xff0c;无法做home和当前位置信息读取&#xff01; 功能&#xff1a; 三个轴的点位运动&#xff1a;前进后退&#xff0c;并分别显示每个轴的移动脉冲数(可以换算为距离)&#xff01; 开发环境&#xff1a;VS2017 硬件设备&#xff1a;固…

编程笔记 Golang基础 007 第一个程序:hello world 使用Goland

编程笔记 Golang基础 007 第一个程序&#xff1a;hello world 使用Goland 步骤1&#xff1a;启动GoLand并创建新项目步骤2&#xff1a;创建主包和主函数步骤3&#xff1a;运行程序小结 开始在Goland环境中编程go语言代码啦。 步骤1&#xff1a;启动GoLand并创建新项目 打开GoL…

[word] word中图片衬于文字下方无法显示 #媒体#微信

word中图片衬于文字下方无法显示 1、如图&#xff0c;图片“衬于文字下方”&#xff0c;文字下方的图象看不见 2、光标这位到图片上这段文字中&#xff0c;点击“格式”&#xff0d;“边框和底纹”&#xff0c;切换到“底纹”选项卡。可发现这两段文字底纹被设置成“白色”了 …

【数学建模入门】

数学建模入门 数学建模需要的学科知识怎么学习数学模型如何读好一篇优秀论文数学建模赛题常见类别数学建模常见问题数学建模组队和分工数学建模准备工作 数学建模需要的学科知识 怎么学习数学模型 &#x1f4a6;推荐阅读书籍&#xff1a; 《数学建模算法与应用》&#xff0c;…