代码随想录算法训练营day20

题目: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.hqwc.cn/news/479923.html

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

相关文章

STM32使用软件SPI协议操作TFT18彩屏

时间记录&#xff1a;2024/2/20 一、SPI协议介绍 &#xff08;1&#xff09;SPI设备通过4根线进行通信&#xff0c;CS片选线&#xff0c;选择从设备&#xff0c;SCK时钟线&#xff0c;由主设备产生时钟&#xff0c;主机MOSI线连从机MISO线&#xff0c;由主机向从机发送信息&am…

Softing OPC UA SIS(安全集成服务器)最新版本集成了MQTT协议

Softing工业自动化的安全集成服务器软件&#xff08;Secure Integration Server, SIS&#xff09;最新版本新增了MQTT协议支持&#xff0c;为IT/OT云应用数据集成提供了更多的连接方案以及更高的安全性。 &#xff08;MQTT强化了安全集成服务器安全性和连接功能&#xff09; So…

阿里云服务器租用价格,2024年新版活动报价明细表

2024年阿里云服务器租用价格表更新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年、ECS u1实例2核4G、5M固定带宽、80G ESSD Entry盘优惠价格199元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元、2核4G4M带宽轻量服务器一年165元12个月、2核4G服…

Sample Pairing(ICLR 2018)

paper&#xff1a;Data Augmentation by Pairing Samples for Images Classification 本文的创新点 本文提出了一种新的应用于图像分类的数据增强方法SamplePairing&#xff0c;这种简单的数据增强技术显著提高了所有测试的数据集的分类精度。此外当训练集中的样本数量非常少…

[极客挑战2019]HTTP

这道题考察的是http请求头字段的含义和使用&#xff1b; 具体如下 Referer:来源地址 User-Agent:客户端配置信息&#xff1a;浏览器类型、版本、系统类型等 X-Forwarded-For:代理地址&#xff0c;即数据发出的地址 开始解题&#xff1a;&#xff08;对我这初学者真的烧脑&a…

嵌入式学习第十九天!(时间获取、文件属性和权限的获取、软链接和硬链接)

时间获取&#xff1a; 1. time time_t time(time_t *tloc); 功能&#xff1a;返回1970-01-01到现在的秒数&#xff08;格林威治时间&#xff09; 参数&#xff1a; tloc:存放秒数空间首地址 返回值: 成功返回秒数 失败返回-1 2. localtime struct tm *localtime(const tim…

JavaScript中手动实现Array.prototype.map方法

在前端开发中&#xff0c;我们经常需要对数组进行操作和处理。在JavaScript中&#xff0c;数组是常用的数据类型之一。而数组的map方法可以将一个数组中的每个元素都进行某种操作&#xff0c;并返回一个新的数组。今天&#xff0c;我们就来手动实现JavaScript中数组原型的map方…

System Verilog浅学——1.二进制和运算符

材料来源&#xff1a;B站up:Tan-Yifan 【SystemVerilog常用语法简介】https://www.bilibili.com/video/BV1XA41177of?p14&vd_source1a46c7af8e528520d93f15dd5c760634 二进制 常量 格式&#xff1a;二进制位宽进制符号&#xff08;b:2;h:16;d:10&#xff09;数据 1b1 …

linux 安装、删除 JTAG驱动

安装 安装驱动需要sudo访问权限&#xff0c;所以得手动安装。 在petalinux安装目录下&#xff1a; 文件的路径。 cd tools/xsct/data/xicom/cable_drivers/lin64/install_script/install_drivers 然后执行文件 install_drivers。 sudo ./install_drivers安装成功。 删除 …

智慧城市驿站:智慧公厕升级版,打造现代化城市生活的便捷配套

随着城市化进程的加速&#xff0c;人们对城市生活质量的要求也越来越高。作为智慧城市建设的一项重要组成部分&#xff0c;多功能城市智慧驿站应运而生。它集合了信息技术、设计美学、结构工艺、系统集成、环保节能等多个亮点&#xff0c;将现代科技与城市生活相融合&#xff0…

【嵌入式】CAN总线

1 简介 CAN 是控制器局域网络 (Controller Area Network) 的简称,它是由研发和生产汽车电子产品著称的德国 BOSCH 公司开发的,并最终成为国际标准(ISO11519),是国际上应用最广泛的现场总线之一。 CAN 总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线…

用CSS3画一个三角形

<style> .up{width:0;height:0;border: 100px solid transparent;border-top: 100px solid red;/*红色*/ } .down{width:0;height:0;border: 100px solid transparent;border-bottom: 100px solid blue;/*蓝色*/ } .left{width:0;height:0;border: 100px solid transpare…