435. 无重叠区间
和打气球类似,根据左边界排序,找重叠就跳结果+1,更新最小右边界。需要注意的是,左边界排序再对右边界排序不能取代更新最小右边界,因为存在左边界更大,右边界也更小也是要更新的。
class Solution {
public:
static bool cmp(vector<int>& a, vector<int>& b) {
if (a[0] == b[0]) return a[1] < b[1];
return a[0] < b[0];
}
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end(), cmp);
int res = 0;
for (int i = 1; i < intervals.size(); i++) {
if (intervals[i][0] < intervals[i - 1][1]) {
res++;
intervals[i][1] = min(intervals[i][1], intervals[i - 1][1]);
// intervals[i][1] = intervals[i-1][1];
}
}
return res;
}
};
763.划分字母区间
在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。
在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了(套住了所有出现过的字母边界)。
class Solution {
public:
vector<int> partitionLabels(string s) {
int record[26];
for (int i = 0; i < s.size(); i++) {
record[s[i] - 'a'] = i;
}
vector<int> result;
int left = 0;
int right = 0;
for (int i = 0; i < s.size(); i++) {
right = max(right, record[s[i] - 'a']);
if (i == right) {
result.push_back(right - left + 1);
left = right + 1;
}
}
return result;
}
};
56. 合并区间
类似的套路,先排序左边界,在找有没有交叉区间,交叉就更新右边界,并放到结果集里。
class Solution {
public:
bool static cmp(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(), cmp);
result.push_back(intervals[0]);
for (int i = 1; i < intervals.size(); i++) {
if (intervals[i][0] <= intervals[i - 1][1]) {
result.back()[1] = max(result.back()[1], intervals[i][1]);
intervals[i][1] = max(intervals[i][1], intervals[i - 1][1]);
}
else {
result.push_back(intervals[i]);
}
}
return result;
}
};