2
https://leetcode.com/problems/range-module/4
Idea is to use a height balanced tree to save the intervals. Intervals are5
kept according to the start point. We search for the position where the given6
range can lie, then check the previous if it overlaps and keep iterating7
forward while the intervals are overlapping.10
We first find the range of values in [left, right). Then for each of the11
overlapping intervals, we subtract the common range. Finally if the entire12
range is covered, then the range will become zero.17
const bool operator<(const Interval &b) const {18
// Important to implement for == case, otherwise intervals19
// with same start won't exist20
// return start < b.start || (start == b.start && end < b.end);22
// This is the best way to compare since tuple already have ordering23
// implemented for fields24
return tie(start, end) < tie(b.start, b.end);27
int start = -1, end = -1;28
Interval(int start, int end) : start(start), end(end) {};31
set<Interval> intervals;36
// TC: Searching O(logn) + O(n) Merging, worst case when current interval37
// covers all, insertion would take O(1) SC: O(1)38
void addRange(int left, int right) {39
Interval interval(left, right);40
// Find the position where interval should lie st the next interval's42
auto it = intervals.lower_bound(interval);44
// check if previous overlaps, move the iterator backwards45
if (!intervals.empty() && it != intervals.begin() && prev(it)->end >= interval.start) {47
interval.start = min(it->start, interval.start);50
// merge while intervals overlap51
while (it != intervals.end() && it->start <= interval.end) {52
interval.end = max(it->end, interval.end);53
intervals.erase(it++);55
intervals.insert(interval);58
// TC: Searching O(logn) + O(n) Merging, worst case when current interval59
// covers all SC: O(1)60
bool queryRange(int left, int right) {61
Interval interval(left, right);62
// Range of numbers that needs to be checked63
int range = right - left;64
// Find the position where interval should lie st the next interval's66
auto it = intervals.lower_bound(interval);68
// check if previous interval overlaps the range, previous only69
// covers iff the open end > start of current. [prev.start, prev.end) [left,71
if (!intervals.empty() && it != intervals.begin() && prev(it)->end > interval.start) {72
// remove the common portion73
int common = min(interval.end, prev(it)->end) - interval.start;76
// for all the following overlapping intervals, remove the common portion77
while (it != intervals.end() && it->start <= interval.end) {78
int common = min(interval.end, it->end) - it->start;82
// Check if the entire range was covered or not86
// TC: Searching O(logn) + O(n) Merging, worst case when current interval87
// covers all SC: O(1)88
void removeRange(int left, int right) {89
Interval interval(left, right);90
// Find the position where interval should lie st the next interval's92
auto it = intervals.lower_bound(interval);94
// check if previous overlaps, then move the iterator position backwards95
if (!intervals.empty() && it != intervals.begin() && prev(it)->end > interval.start) --it;97
// For each of the overlapping intervals, remove the common portions98
while (it != intervals.end() && it->start < interval.end) {99
// Start and End of common portion100
int common_start = max(interval.start, it->start);101
int common_end = min(interval.end, it->end);103
// only a section of interval overlaps, remove that part104
// an overlapping interval might have to be broken into two105
// non-overlapping parts Eg [---------------------) Bigger interval106
// [--------) Ongoing interval107
// [------) [-----) Original interval broken into left and right parts109
// check if there is some range left on the left side110
if (it->start < common_start) intervals.insert(Interval(it->start, common_start));112
// check if there is some range left on the right side113
if (it->end > common_end) intervals.insert(Interval(common_end, it->end));115
// Remove the original interval116
intervals.erase(it++);122
* Your RangeModule object will be instantiated and called as such:123
* RangeModule* obj = new RangeModule();124
* obj->addRange(left,right);125
* bool param_2 = obj->queryRange(left,right);126
* obj->removeRange(left,right);