LC 435. 无重叠区间
题目链接:LC 435. 无重叠区间
思路:统计最大的非重叠区间的个数,再让总区间个数减去非重叠区间个数就最少的是删除区间的个数。**如何统计最大非重叠区间的个数呢?**像上一篇文章讲的类似,对区间进行排序,然后遍历区间,若区间去上一区间有重叠的,就更新重叠区间边界;若区间去上一区间没有重叠的,就增加非重叠区间个数。
代码:
class Solution {
public:
//本题要求删除最少个数的区间使剩下的区间不重叠;
//也就是找到数量最多的不重叠区间,让总数减去不重叠区间的数目即可
static bool cmp(const vector<int>& a, const vector<int>&b){
return a[0]<b[0];
}
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
//起始位置从小到大排序
sort(intervals.begin(), intervals.end(), cmp);
int num = 1;//统计非重叠区间的个数
for(int i=1; i<intervals.size(); i++){
if(intervals[i][0]>=intervals[i-1][1]){//该区间与上个区间没有重叠的
num++;
}
else{
intervals[i][1] = min(intervals[i-1][1], intervals[i][1]);
}
}
int result = intervals.size()-num;
return result;
}
};
LC 763.划分字母区间
题目链接:LC 763.划分字母区间
思路:本题不算贪心,没有体现局部最优到全局最优;思路就是找到每个字母出现的最后位置;然后遍历数组,若出现的最后位置与遍历的下标相同,那么就可以进行划分;划分时要注意,第一次划分要让下标减去-1才可以得到划分的个数,后面只需让下标减去上次划分得到的下标即可。
代码:
class Solution {
public:
//统计每个字符出现的最后位置,然后遍历数组,当遍历数组下标等于遍历的字符中最大的最后位置时,就可以分割。
//如何统计每个字符的最后位置?用哈希表
vector<int> partitionLabels(string s) {
vector<int> hash(26, 0);//26个英文字母,都初始化为0
//得到每个字母的最后位置
for(int i=0; i<s.size(); i++){
hash[s[i]-'a'] = i;
}
vector<int> result;
int max = -1;
int perid = -1;
for(int j=0; j<s.size(); j++){
if(max<hash[s[j]-'a']){
max = hash[s[j]-'a'];
}
if(max == j){
result.push_back(j-perid);
perid = j;
}
}
return result;
}
};
LC 56. 合并区间
题目链接:LC 56. 合并区间
思路:将区间按照起始位置进行排序,然后依次插入到result中,若插入的区间和result最后的区间有重叠就将result最后一个区间进行扩充;若没有重叠就直接将遍历的区间插入result中。
代码:
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) {
sort(intervals.begin(), intervals.end(), cmp);
vector<vector<int>> result;
result.push_back(intervals[0]);
for(int i=1; i<intervals.size(); i++){
if(intervals[i][0]>result.back()[1]){
result.push_back(intervals[i]);
}
else{
result.back()[1] = max(intervals[i][1], result.back()[1]);
}
}
return result;
}
};