56.合并区间
思路:
按左区间排序;
遍历所有区间,如果当前区间的左边界小于等于上一个区间的右边界,则合并区间(新区间的左边界为上一个区间的左边界,新区间的右边界为上一个区间的有边界和当前区间有边界中较大的一个)
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
vector<vector<int>> result;
sort(intervals.begin(), intervals.end(), [](vector<int>& lhs, vector<int>& rhs){ return lhs[0] < rhs[0]; });
for(int i = 0; i < intervals.size(); ++i) {
// 合并区间
if(i > 0 && intervals[i][0] <= intervals[i - 1][1]) {
intervals[i][0] = intervals[i - 1][0];
intervals[i][1] = max(intervals[i - 1][1], intervals[i][1]);
} else {
// 区间不重复,将上一个区间添加到结果集中
if(i > 0) {
result.push_back(intervals[i - 1]);
}
}
// 遍历到最后一个区间,直接将其添加到结果集中
if(i == intervals.size() - 1) result.push_back(intervals[i]);
}
return result;
}
};
738.单调递增的数字
题目链接 文章讲解 视频讲解
暴力解法
评价-->超时
class Solution {
public:
int monotoneIncreasingDigits(int n) {
while(n) {
if(isIncreasing(n)) return n;
n--;
}
return -1;
}
bool isIncreasing(int n) {
int pre = n % 10;
while(n) {
n = n / 10;
int cur = n % 10;
if(pre < cur) return false;
pre = cur;
}
return true;
}
};
贪心
思路:
从后向前遍历,如果当前数字比前一位数字小,则前一个数字减一(借位),当前位变为9
特殊情况1000,如果不做处理的话,从后向前遍历会得到结果0900,转为数字后是900,不是最大的。
所以用flag记录当前需要边为9的索引,从索引开始向右全部变为9,因为右边必须要大于等于左边,所以应全部变为9
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string s_n = to_string(n);
int flag = s_n.size();
for(int i = s_n.size() - 1; i > 0; --i) {
if(s_n[i] < s_n[i - 1]) {
flag = i;
s_n[i - 1]--;
}
}
// 将flag向右的所有数字变为9
for(int i = flag; i < s_n.size(); ++i) {
s_n[i] = '9';
}
return stoi(s_n);
}
};
标签:vector,return,int,56,随想录,intervals,第三十七,区间,size
From: https://www.cnblogs.com/cscpp/p/18246899