代码随想录算法训练营第31天 | 56.合并区间、738.单调递增的数字
56.合并区间
解题思路
按照左边界排序,排序后:
局部最优:每次合并都取最大的右边界,这样就可以合并更多的区间
全局最优:合并所有重叠的区间
代码实现
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;
sort(intervals.begin(), intervals.end());
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]);
}
}
return result;
}
};
题目总结
对于贪心算法,没有什么套路和框架,需要多练习常规解法,这样遇到类似题目时能够有思路。
738.单调递增的数字
解题思路
局部最优:遇到 strNum[i-1]>strNum[i] 的情况,首先将 strNum[i-1] 减一,然后将 strNum[i] 赋值为9,可以将这两个数变成最大单调递增的整数
全局最优:得到小于或等于 N 的最大单调递增的整数
代码实现
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string strNum = to_string(n);
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);
}
};
题目总结
本题中的 flag 用来标定赋值9从哪里开始,设置为默认值,为了防止在 flag 没有被赋值的情况下执行第二个 for 循环。