435. 无重叠区间
题目:力扣
class Solution {
public:
static const bool cmp(vector<int>& a,vector<int>& b ){
if(a[1] == b[1]) return a[0] < b[0];
return a[1] < b[1];
}
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
sort(intervals.begin(),intervals.end(),cmp);
int ans = 0;
int end = 0;
int start = 0;
int min_end = INT_MAX;
for(int i = 0; i < intervals.size(); ++i){
start = intervals[i][0];
end = intervals[i][1];
min_end = min(end,min_end);
if(start >= min_end){
ans++;
min_end = end;
}
}
ans = intervals.size() - ans - 1;
return ans;
}
};
763.划分字母区间
题目:力扣
//转化为合并区间来做
class Solution {
public:
static const bool cmp(vector<int>& a,vector<int>& b){
if(a[0] == b[0]) return a[1] < b[1];
return a[0] < b[0];
}
vector<int> partitionLabels(string s) {
unordered_map<char,vector<int>> num;
vector<int> ans;
for(int i = 0; i < s.size(); ++i){
if(num.find(s[i]) == num.end()){
num[s[i]]= {i,i};
}else{
num[s[i]][1] = i;
}
}
vector<vector<int> > mind;
for(auto a : num){
mind.push_back(a.second);
}
sort(mind.begin(),mind.end(),cmp);
mind.push_back({INT_MAX,INT_MAX});
int start = 0;
int end = 0;
int max_end = -1;
int min_start = INT_MAX;
for(int i = 0; i < mind.size(); ++i){
start = mind[i][0];
end = mind[i][1];
min_start = min(start,min_start);
if(max_end != -1 && start >= max_end){
ans.push_back(max_end - min_start + 1);
min_start = start;
}
max_end = max(end,max_end);
}
return ans;
}
};
//另一种方法,统计字符出现的最后位置,然后遍历,如果最远边界和下标相等则记录
class Solution {
public:
vector<int> partitionLabels(string S) {
int hash[27] = {0}; // i为字符,hash[i]为字符出现的最后位置
for (int i = 0; i < S.size(); i++) { // 统计每一个字符最后出现的位置
hash[S[i] - 'a'] = i;
}
vector<int> result;
int left = 0;
int right = 0;
for (int i = 0; i < S.size(); i++) {
right = max(right, hash[S[i] - 'a']); // 找到字符出现的最远边界
if (i == right) {
result.push_back(right - left + 1);
left = i + 1;
}
}
return result;
}
};
56. 合并区间
题目:力扣
class Solution {
public:
static const bool cmp(vector<int>& a, vector<int>& b){
return a[0] < b[0];
}
vector<vector<int>> merge(vector<vector<int>>& intervals) {
sort(intervals.begin(),intervals.end(),cmp);
vector<vector<int>> ans;
intervals.push_back({INT_MAX,INT_MAX});
int start = 0;
int end = 0;
int min_start = INT_MAX;
int max_end = -1;
for(int i = 0; i < intervals.size(); ++i){
start = intervals[i][0];
end = intervals[i][1];
min_start = min(start,min_start);
if(max_end != -1 && start > max_end){
ans.push_back({min_start,max_end});
min_start = start;
}
max_end = max(end,max_end);
}
return ans;
}
};
//另一种方法,不断合并大的区间即可
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.push_back(intervals[0]);
for (int i = 1; i < intervals.size(); i++) {
if (result.back()[1] >= intervals[i][0]) { // 合并区间
result.back()[1] = max(result.back()[1], intervals[i][1]);
} else {
result.push_back(intervals[i]);
}
}
return result;
}
};
总结
题型:贪心(重叠区间)
技巧:排序+遍历。