Skip to content

Commit de540ec

Browse files
committed
Runtime: 234 ms (Top 86.20%) | Memory: 71.1 MB (Top 79.66%)
1 parent da9bfab commit de540ec

File tree

1 file changed

+32
-31
lines changed

1 file changed

+32
-31
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
// Runtime: 234 ms (Top 86.20%) | Memory: 71.1 MB (Top 79.66%)
12
/*
23
https://leetcode.com/problems/range-module/
3-
4+
45
Idea is to use a height balanced tree to save the intervals. Intervals are kept
56
according to the start point.
67
We search for the position where the given range can lie, then check the previous if it overlaps
78
and keep iterating forward while the intervals are overlapping.
8-
9-
QueryRange:
9+
10+
QueryRange:
1011
We first find the range of values in [left, right). Then for each of the overlapping intervals,
1112
we subtract the common range. Finally if the entire range is covered, then the range will become zero.
1213
*/
@@ -17,56 +18,56 @@ class RangeModule {
1718
// Important to implement for == case, otherwise intervals
1819
// with same start won't exist
1920
// return start < b.start || (start == b.start && end < b.end);
20-
21+
2122
// This is the best way to compare since tuple already have ordering implemented for
2223
// fields
2324
return tie(start, end) < tie(b.start, b.end);
2425
}
25-
26+
2627
int start = -1, end = -1;
2728
Interval(int start, int end): start(start), end(end) {};
2829
};
29-
30+
3031
set<Interval> intervals;
3132
public:
3233
RangeModule() {
33-
34+
3435
}
35-
36+
3637
// TC: Searching O(logn) + O(n) Merging, worst case when current interval covers all, insertion would take O(1)
3738
// SC: O(1)
3839
void addRange(int left, int right) {
3940
Interval interval(left, right);
40-
// Find the position where interval should lie st the next interval's
41+
// Find the position where interval should lie st the next interval's
4142
// start >= left
4243
auto it = intervals.lower_bound(interval);
43-
44+
4445
// check if previous overlaps, move the iterator backwards
4546
if(!intervals.empty() && it != intervals.begin() && prev(it)->end >= interval.start) {
4647
--it;
4748
interval.start = min(it->start, interval.start);
4849
}
49-
50+
5051
// merge while intervals overlap
5152
while(it != intervals.end() && it->start <= interval.end) {
5253
interval.end = max(it->end, interval.end);
5354
intervals.erase(it++);
5455
}
5556
intervals.insert(interval);
5657
}
57-
58+
5859
// TC: Searching O(logn) + O(n) Merging, worst case when current interval covers all
5960
// SC: O(1)
6061
bool queryRange(int left, int right) {
6162
Interval interval(left, right);
6263
// Range of numbers that needs to be checked
6364
int range = right - left;
64-
// Find the position where interval should lie st the next interval's
65+
// Find the position where interval should lie st the next interval's
6566
// start >= left
6667
auto it = intervals.lower_bound(interval);
67-
68+
6869
// check if previous interval overlaps the range, previous only
69-
// covers iff the open end > start of current. [prev.start, prev.end) [left, right)
70+
// covers iff the open end > start of current. [prev.start, prev.end) [left, right)
7071
if(!intervals.empty() && it != intervals.begin() && prev(it)->end > interval.start) {
7172
// remove the common portion
7273
int common = min(interval.end, prev(it)->end) - interval.start;
@@ -81,39 +82,39 @@ class RangeModule {
8182
// Check if the entire range was covered or not
8283
return range == 0;
8384
}
84-
85+
8586
// TC: Searching O(logn) + O(n) Merging, worst case when current interval covers all
8687
// SC: O(1)
8788
void removeRange(int left, int right) {
8889
Interval interval(left, right);
89-
// Find the position where interval should lie st the next interval's
90+
// Find the position where interval should lie st the next interval's
9091
// start >= left
9192
auto it = intervals.lower_bound(interval);
92-
93+
9394
// check if previous overlaps, then move the iterator position backwards
94-
if(!intervals.empty() && it != intervals.begin() && prev(it)->end > interval.start)
95+
if(!intervals.empty() && it != intervals.begin() && prev(it)->end > interval.start)
9596
--it;
96-
97+
9798
// For each of the overlapping intervals, remove the common portions
9899
while(it != intervals.end() && it->start < interval.end) {
99100
// Start and End of common portion
100101
int common_start = max(interval.start, it->start);
101102
int common_end = min(interval.end, it->end);
102-
103+
103104
// only a section of interval overlaps, remove that part
104105
// an overlapping interval might have to be broken into two non-overlapping parts
105-
// Eg [---------------------) Bigger interval
106-
// [--------) Ongoing interval
107-
// [------) [-----) Original interval broken into left and right parts
108-
106+
// Eg [---------------------) Bigger interval
107+
// [--------) Ongoing interval
108+
// [------) [-----) Original interval broken into left and right parts
109+
109110
// check if there is some range left on the left side
110-
if(it->start < common_start)
111-
intervals.insert(Interval(it->start, common_start));
112-
111+
if(it->start < common_start)
112+
intervals.insert(Interval(it->start, common_start));
113+
113114
// check if there is some range left on the right side
114-
if(it->end > common_end)
115+
if(it->end > common_end)
115116
intervals.insert(Interval(common_end, it->end));
116-
117+
117118
// Remove the original interval
118119
intervals.erase(it++);
119120
}
@@ -126,4 +127,4 @@ class RangeModule {
126127
* obj->addRange(left,right);
127128
* bool param_2 = obj->queryRange(left,right);
128129
* obj->removeRange(left,right);
129-
*/
130+
*/

0 commit comments

Comments
 (0)