又是难绷的一天啊,第二题和第三题看完视频才AC的,第一道题又被官方测试样例恶心了,下面细说。
56. 合并区间
这道题没有什么新的思路,还是先将区间按照区间左值排序,然后遍历向量中的每一个区间,如果和前一个区间有重叠的话就合并,没有重叠的话就把上一个存储的区间存入结果中,但是!!!!!!为什么要给这么一个测试案例,直接报错了,然后还排查不了原因,因为输入样例实在是太长了,根本不能把完整的测试样例复制进来,导致我无法debug,我不想充力扣的会员。。。。
后面发现写的谓词有问题,把return a[0] <= b[0];
改成return a[0] < b[0];
就AC了,但是为什么呢?我真的很想知道,问群助手也不回我,去题目的评论区也找不到类似的问题,可能是因为我这个bug太小众了吧,真的很无语。
这是正确的代码
class Solution {
public:static bool My_Compare(vector<int> &a, vector<int> &b){return a[0] < b[0];}vector<vector<int>> merge(vector<vector<int>>& intervals) {vector<vector<int>> result;//需要先按区间左值对数组排序sort(intervals.begin(), intervals.end(), My_Compare);int Start = intervals[0][0];for(int i = 1; i < intervals.size(); i++){if(intervals[i][0] <= intervals[i - 1][1]) //出现重叠intervals[i][1] = max(intervals[i][1], intervals[i - 1][1]);else{result.push_back({Start, intervals[i - 1][1]});Start = intervals[i][0];} }result.push_back({Start, intervals[intervals.size() - 1][1]});return result;}
};
738.单调递增的数字
这道题没思路,直接看讲解了。这道题首先要明确一个规则:从后向前遍历才能得到正确结果,从前往后遍历可能会输出非递增的结果,332这个测试样例就是比较好的说明。为了方便遍历,首先把输入的数字转换为字符串,从后往前遍历,需要比较当前数字和前面一位数字的大小关系,如果当前数字>=前面的数字,则已经满足递增关系,则无需变动,但如果出现当前的数字比前面的小,则需要将前一位数字减一,当前数字标记为9的起始位置。在循环中不断更新9的起始位置,循环结束后再用一个for循环从最新的位置开始向后遍历,遍历到的数字一律改为9。当然,也有可能整个循环下来都不需要有位置标记为9,因此标记需要初始化为整个数字的最末端+1(s.size())。
class Solution {
public:int monotoneIncreasingDigits(int n) {string s = to_string(n);int flag = s.size();for(int i = s.size() - 1; i > 0; i--){if(s[i] < s[i - 1]){ //高位的数字比低位的大s[i - 1] = s[i - 1] - 1;flag = i;}}for(int i = flag; i < s.size(); i++)s[i] = '9';return stoi(s);}
};
968.监控二叉树
这道题太难了,直接看讲解去了。这道题目综合了很多知识点,二叉树,递归,贪心。。。首先需要对所有节点的可能状态进行分类,所有节点只可能有三种状态:0.未覆盖;1.有摄像头;2.被覆盖。所以我们需要统计状态为1的节点数。其次,我们需要明确贪心的思路,怎么才能让安装的摄像头数量最少?我们就需要自底向上去遍历二叉树,且尽可能避免在叶子节点安装摄像头,而是在未被覆盖的节点的父节点处安装摄像头。有了这个贪心的原则以后,我们还需要明确如何递归遍历二叉树,这里必须要用后续遍历,因为只有先知道了左右孩子的状态,才能确定当前节点是否应该安装摄像头。明确了这三点之后就可以写代码了。但是这里还有种特殊情况,就是遍历完二叉树以后根节点可能还是未覆盖的状态,所以要单独对这种情况做一个判断,在主函数中调用递归函数判断根节点状态,如果根节点状态为0的话还需要result++。
/*** 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;int Traversal(TreeNode* node){//所有节点只有3个状态:// 0. 未被覆盖 1. 有摄像头 2.已覆盖//确定终止条件if(node == NULL) return 2; //空节点只能是已覆盖状态//后序遍历int left = Traversal(node -> left); //左int right = Traversal(node -> right); //右//中if(left == 2 && right == 2) //左右孩子都已被覆盖return 0;if(left == 0 || right == 0){ //左右孩子至少有一个未被覆盖,必须装摄像头result++;return 1;} if(left == 1 || right == 1)return 2;return -1;}int minCameraCover(TreeNode* root) {if(Traversal(root) == 0)result += 1;return result;}
};
今天真的抽象,好多抽象的事,还有抽象的题,麻了。