题目来源
题目描述
class SummaryRanges {
private:
public:
SummaryRanges() {}
void addNum(int val) {
}
vector<vector<int>> getIntervals() {
}
};
题目解析
插入区间
这道题和leetcode:57.插入区间差不多。
- 每次进来一个新的数字val,都会生成一个新的区间newInterval = [val,val],并且新建一个空的区间数组res,以及一个变量curr来保存要在现有区间数组中加入新区间的位置
- 然后遍历现有区间数组intervals,对每一个遍历到的当前区间interval:
- 如果要newInterval的起始位置 > interval的结束位置 + 1,说明二者没有交集,直接将interval压入res,然后curr++
- 否则,二者有交集,需要合并,此时用二者起始位置中较小的去更新newInterval的起始位置,用较大的结束位置去更新newInterval的结束位置
- 最终将要加入区间放在 res 中的 cur 位置,然后将 res 赋值给 intervals 即可
class SummaryRanges {
private:
std::vector<std::vector<int>> intervals;
public:
SummaryRanges() {}
void addNum(int val) {
std::vector<int> newInterval{val, val};
std::vector<std::vector<int>> res;
int curr = 0;
for(auto interval : intervals){
if(newInterval[1] + 1 < interval[0]){
res.push_back(interval);
}else if(newInterval[0] > interval[1] + 1){
res.push_back(newInterval);
++curr;
}else{
newInterval[0] = min(newInterval[0], interval[0]);
newInterval[1] = max(newInterval[1], interval[1]);
}
}
res.insert(res.begin() + curr, newInterval);
intervals = res;
}
vector<vector<int>> getIntervals() {
return intervals;
}
};
由于上面的方法每次添加区间的时候,都要把 res 赋值给 intervals,整个区间数组都要进行拷贝,十分的不高效。怎么办呢?
- 用一个变量overlap来记录所有跟要加入区间有重叠的区间的个数,用变量i表示新区间要插入的位置
- 这样只要最后overlap大于0,就将intervals中这些重合的区间删掉,然后再将新区间插入
class SummaryRanges {
public:
SummaryRanges() {}
void addNum(int val) {
vector<int> newInterval{val, val};
int i = 0, overlap = 0, n = intervals.size();
for (; i < n; ++i) {
if (newInterval[1] + 1 < intervals[i][0]) break;
if (newInterval[0] <= intervals[i][1] + 1) {
newInterval[0] = min(newInterval[0], intervals[i][0]);
newInterval[1] = max(newInterval[1], intervals[i][1]);
++overlap;
}
}
if (overlap > 0) {
intervals.erase(intervals.begin() + i - overlap, intervals.begin() + i);
}
intervals.insert(intervals.begin() + i - overlap, newInterval);
}
vector<vector<int>> getIntervals() {
return intervals;
}
private:
vector<vector<int>> intervals;
};