前言
之前就有刷代码随想录,但奈何总是三天打鱼两天晒网,而且刷的也很囫囵吞枣,于是乎决定参加代码随想录训练营,准备精刷一遍,希望自己能坚持下去,结营后自己的算法水平能更上一个level,冲ing!
leetcode56. 合并区间
题目链接leetcode56. 合并区间
思路
本题和之前的452. 用最少数量的箭引爆气球和 435. 无重叠区间都是一个套路,只是在判断出重叠区间后多了将重叠区间合并的要求。
具体思路:依然是先对区间按左边界排序,然后将第一个区间先放进结果集中,后面如果有重叠,直接在result中合并,然后就是循环中判断重叠,如果有重叠 (当前区间左边界<=result.back的右边界,进行合并:合并的思路是直接更新右边界,因为result.back()的左边界一定是最小值,因为之前已经按照左边界排序了),如果没重叠,直接将当前区间放进result中。
代码
cpp
class Solution {
public:
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上直接合并
result.push_back(intervals[0]);
for (int i = 1; i < intervals.size(); i++) {
if (result.back()[1] >= intervals[i][0]) { // 发现重叠区间
// 合并区间,只更新右边界就好,因为result.back()的左边界一定是最小值,因为我们按照左边界排序的
result.back()[1] = max(result.back()[1], intervals[i][1]);
} else {
result.push_back(intervals[i]); // 区间不重叠
}
}
return result;
}
};
leetcode738.单调递增的数字
思路
以98为例,如何找到小于该数的最大递增数字?一旦出现strNum[i - 1] > strNum[i]的情况(非单调递增),首先想让strNum[i - 1]--,然后strNum[i]给为9,这样这个整数就是89,即小于98的最大的单调递增整数。另外还要考虑遍历顺序,只有从后向前遍历才能重复利用上次比较的结果。
最后代码实现的时候,需要用一个flag来标记从哪里开始赋值9。
代码
cpp
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string strNum = to_string(n);
// flag用来标记赋值9从哪里开始
// flag设置为这个默认值,为了防止第二个for循环在flag没有被赋值的情况下执行
int flag = strNum.size();
for (int i = strNum.size() - 1; i > 0; i--) {
if (strNum[i - 1] > strNum[i] ) {
flag = i;
strNum[i - 1]--;
}
}
for (int i = flag; i < strNum.size(); i++) {
strNum[i] = '9';
}
return stoi(strNum);
}
};