题目来源
题目描述
class RangeModule {
private:
public:
RangeModule() {
}
void addRange(int start, int end) {
}
bool queryRange(int start, int end) {
}
void removeRange(int start, int end) {
}
};
题目分析
题意
- 这道题让我们实现一个RangeModule的类,里面有三个功能函数:
- 插入范围
- 查找范围
- 删除范围
区间操作
(1) 插入操作就是57. insert interval这道题
(2) 查找范围:
- 查找是否有一个范围完全覆盖了要查找的范围;如果有,返回true;否则返回false
(3) 删除范围
- 类似插入范围。
- 已知待删除的范围是deleteInterval = [start,end),现有范围是Intervals
- 我们先新建一个res存结果
- 然后遍历已有的范围Intervals:
- 如果currInterval.end <= deleteInterval.start,说明没有重叠,将currInterval压入res,并且curr++来记录当前位置
- 如果deleteInterval.end <= currInterval.start,说明没有重叠,将currInterval压入res
- 否则就是有重叠。需要删除:删除时可能将原来的大范围变为两个/一个/零个小范围,所以我们用一个临时数组t来存break掉后的小范围。
- 如果当前范围的起始位置小于要删除的范围的起始位置left,说明此时一定有一段范围留下来了,即从当前范围的起始位置到要删除的范围的起始位置left,将这段范围加入临时数组t
- 同理,如果当前范围的结束位置大于要删除的范围的结束位置right,将这段范围加入临时数组t。
- 最后将数组t加入结果res中的cur位置即可
class RangeModule {
private:
std::vector<std::pair<int, int>> intervals;
public:
RangeModule() {
}
void addRange(int start, int end) {
std::vector<std::pair<int, int>> res;
int n = intervals.size(), curr = 0;
for (int i = 0; i < n; ++i) {
if(intervals[i].second < start){
res.push_back(intervals[i]);
++curr;
}else if(end < intervals[i].first ){
res.push_back(intervals[i]);
}else{
start = std::min(start, intervals[i].first);
end = std::max(end, intervals[i].second);
}
}
res.insert(res.begin() + curr, {start, end});
intervals = res;
}
bool queryRange(int start, int end) {
for(auto a : intervals){
if(a.first <= start && a.second >= end){
return true;
}
}
return false;
}
void removeRange(int start, int end) {
vector<pair<int, int>> res, t;
int n = intervals.size(), cur = 0;
for (int i = 0; i < n; ++i) {
if (intervals[i].second <= start) {
res.push_back(intervals[i]);
++cur;
} else if (intervals[i].first >= end) {
res.push_back(intervals[i]);
} else {
if (intervals[i].first < start) {
t.push_back({intervals[i].first, start});
}
if (intervals[i].second > end) {
t.push_back({end, intervals[i].second});
}
}
}
res.insert(res.begin() + cur, t.begin(), t.end());
intervals = res;
}
};