LeetCode435. 无重叠区间
和上题引爆气球的逻辑非常像,只要想到左边界排序之后,更新右边界为最小值,则就可以轻松写出代码,如果按照右边界来排序,则就可以省去取最小值的逻辑。
代码如下:时间复杂度O(nlogn);空间复杂度O(n)(快排)
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 result = 0;
for(int i=1;i<intervals.size();i++){
if(intervals[i][0]<intervals[i-1][1]){
result++;
intervals[i][1] = min(intervals[i-1][1],intervals[i][1]);
}
}
return result;
}
};
LeetCode763.划分字母区间
本题首先记录每个字母最远出现的下标,然后不断遍历字符,判断是否到达最远下标,如果达到,则该下标之前的字符串可以作为一个字串保留。
本题的妙处:哈希表储存最远下标;max值不断维护最远下标。
代码如下:时间复杂度O(n);空间复杂度O(1)哈希表为固定大小。
class Solution {
public:
vector<int> partitionLabels(string s) {
int hash[27]={0};
vector<int> result;
for(int i=0;i<s.size();i++){
hash[s[i]-'a'] = i;
}
int end = hash[s[0]-'a'];
int pre_end = 0;
for(int i=0;i<s.size();i++){
if(i==end){
result.push_back(end+1-pre_end);
pre_end = end+1;
if(end==s.size()-1) break;
end = hash[s[i+1]-'a'];
}
end = max(end,hash[s[i]-'a']);
}
return result;
}
};
LeetCode56. 合并区间
前面的题是在求交集,那么本题就是求并集,逻辑是一样的,如果重叠,更新右边界,不重叠,插入result数组中,左右边界都更新。代码如果简洁点可以直接利用result.back()[1]这种形式进行操作。
代码如下:时间复杂度O(nlogn);空间复杂度O(n)(快排)。
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];
}
vector<vector<int>> merge(vector<vector<int>>& intervals) {
sort(intervals.begin(),intervals.end(),cmp);
vector<vector<int>> result;
vector<int> interval(2,0);
interval[0] = intervals[0][0];
interval[1] = intervals[0][1];
for(int i=1;i<intervals.size();i++){
if(intervals[i][0]>interval[1]){
result.push_back(interval);
interval[0] = intervals[i][0];
interval[1] = intervals[i][1];
}else if(intervals[i][0]<=interval[1]){
interval[1] = max(intervals[i][1],interval[1]);
}
}
result.push_back(interval);
return result;
}
};