欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 代码随想录算法训练营day31

代码随想录算法训练营day31

2025/2/23 17:16:20 来源:https://blog.csdn.net/qq_38365428/article/details/145193688  浏览:    关键词:代码随想录算法训练营day31

代码随想录算法训练营

—day31

文章目录

  • 代码随想录算法训练营
  • 前言
  • 一、 56. 合并区间
  • 二、738. 单调递增的数字
  • 三、968.监控二叉树
  • 总结


前言

今天是算法营的第31天,希望自己能够坚持下来!
今日任务:
● 56. 合并区间
● 738.单调递增的数字
● 968.监控二叉树


一、 56. 合并区间

题目链接
文章讲解
视频讲解
在这里插入图片描述

思路:
1.先对区间以左边界进行排序
2.遍历区间,重叠的就对区间进行合并,更新右边界;不重叠的直接放入结果集
这里有个技巧,把第一个区间直接放入结果集,然后遍历的时候直接在结果集中进行合并区间

class Solution {
public:// static bool cmp(const vector<int>& a, const vector<int>& b) {//     return a[0] < b[0];// }vector<vector<int>> merge(vector<vector<int>>& intervals) {vector<vector<int>> result;if (intervals.size() == 0) return result;//用lambda表达式sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b) {return a[0]<b[0];});//第一个区间直接放入结果集,之后在结果集中进行合并result.push_back(intervals[0]);for (int i = 1; i < intervals.size(); i++) {if (intervals[i][0] <= result.back()[1]) { //重叠//合并区间,就是更新结果集里面的右边界,左边界已经按大小排序了,只有右边界需要判断取最大值result.back()[1] = max(intervals[i][1], result.back()[1]);} else {result.push_back({intervals[i][0], intervals[i][1]}); //不重叠}}return result;}
};

二、738. 单调递增的数字

题目链接
文章讲解
视频讲解

思路:

  1. 将数字转成字符串来处理
  2. 后序遍历,如果左边数字比当前数字大,记录当前数字位置flag,并且左边数字-1
  3. 记录的flag及以后的数字都变成9

代码如下:

class Solution {
public:int monotoneIncreasingDigits(int n) {string s = to_string(n); //转成字符串来处理int flag = s.size(); //记录需要变成9的数字位置for (int i = s.size() - 1; i > 0; i--) { //后序遍历,一直到第二个数字if (s[i - 1] > s[i]) { //左边数字比右边大flag = i;s[i - 1]--; //左边的数字-1,后面的数字全部变成9}}//flag位置及后面的数字全部变成9for (int i = flag; i < s.size(); i++) {s[i] = '9';}return stoi(s);}
};

三、968.监控二叉树

题目链接
文章讲解
视频讲解

思路:
整体思路是让叶子节点的父节点放监控,可以覆盖到叶子节点和父节点的父节点两层。

定义二叉树节点的三种状态:
0.无覆盖
1.有监控
2.有覆盖

思考空节点是什么状态:
空节点需要返回2有覆盖,因为空节点如果返回0和1都会影响“让叶子节点的父节点放监控”这个最初的设定。

思考遍历顺序:
需要左右节点反馈结果给中间节点,使用后序遍历。

递归三部曲:
1.递归的参数和返回值:参数是节点,返回值是自定义的三种节点状态(0,1,2)
2.终止条件:遇到空节点终止。
3.单层递归逻辑:
有三种情况:
情况一:左右节点都有覆盖,那么当前节点无覆盖,需要当前节点的父节点放监控,返回0
情况二:左右任一节点无覆盖,那么当前节点都需要放监控,返回1(result++)
情况三:左右任一节点有监控,那么当前节点就是有覆盖,返回2
还有一种情况,情况四:到根节点的时候返回的是无覆盖,本来需要在当前节点的父节点放监控的,但是根节点已经没有父节点了,那么需要在根节点也放一个监控。
代码如下:

/*** 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:int result;//定义三种状态,0:无覆盖,1:有摄像头 2:有覆盖//叶子节点往上遍历,使用后序遍历(左右中)//叶子节点的父节点放摄像头int traversal(TreeNode* root) {//空节点返回2有覆盖if (root == nullptr) return 2;int left = traversal(root->left);int right = traversal(root->right);//1.左右节点都有覆盖,当前节点无覆盖,返回0(父节点安装摄像头)if (left == 2 && right == 2) return 0;//2.左右节点任意一个无覆盖,当前节点安装摄像头,返回1if (left == 0 || right == 0) {result++;return 1;}//3.左右节点任意一个有摄像头,当前节点有覆盖,返回2if (left == 1 || right == 1) return 2;return -1;}int minCameraCover(TreeNode* root) {result = 0;//4.根节点返回0,本来需要在其父节点安装摄像头来覆盖的,需要加多一个摄像头在根节点if (traversal(root) == 0) result++;return result;}
};

总结

贪心算法终于结束了,之前没接触过贪心算法,学完这一章后受益匪浅。每次看题目都会不禁“啊?”,然后看完题解又会有种茅塞顿开的感觉!

明天继续加油!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词