Leetcode 715. Range Module
Problem:
A Range Module is a module that tracks ranges of numbers. Your task is to design and implement the following interfaces in an efficient manner.
addRange(int left, int right)
Adds the half-open interval[left, right)
, tracking every real number in that interval. Adding an interval that partially overlaps with currently tracked numbers should add any numbers in the interval[left, right)
that are not already tracked.queryRange(int left, int right)
Returns true if and only if every real number in the interval[left, right)
is currently being tracked.removeRange(int left, int right)
Stops tracking every real number currently being tracked in the interval[left, right)
.
Example 1:
addRange(10, 20): null removeRange(14, 16): null queryRange(10, 14): true (Every number in [10, 14) is being tracked) queryRange(13, 15): false (Numbers like 14, 14.03, 14.17 in [13, 15) are not being tracked) queryRange(16, 17): true (The number 16 in [16, 17) is still being tracked, despite the remove operation)
Note:
- A half open interval
[left, right)
denotes all real numbersleft <= x < right
. 0 < left < right < 10^9
in all calls toaddRange, queryRange, removeRange
.- The total number of calls to
addRange
in a single test case is at most1000
. - The total number of calls to
queryRange
in a single test case is at most5000
. - The total number of calls to
removeRange
in a single test case is at most1000
.
Solution:
Leetcode 57. Insert Interval的升级版,addRange函数一样,removeRange函数如果segments[i]和要删除的部分没有重叠,则添加到结果集中,如果有重叠则分为两种情况:
1. --------- segments[i]
---------
left如果大于segments[i]的first,则添加(segments[i].first,left)
2. --------- segments[i]
---------
right如果小于segments[i]的second,则添加(right,segments[i].second)
对于queryRange函数,简单的二分查找即可
Code:
1 class RangeModule { 2 public: 3 RangeModule() { 4 5 } 6 7 void addRange(int left, int right) { 8 auto iter = segments.begin(); 9 while(iter != segments.end() && (*iter).first < left) 10 iter++; 11 segments.insert(iter,make_pair(left,right)); 12 vector<pair<int,int>> result; 13 for(int i = 0;i != segments.size();++i){ 14 if(result.empty() || segments[i].first > result.back().second) 15 result.push_back(segments[i]); 16 else{ 17 result.back().second = max(result.back().second,segments[i].second); 18 } 19 } 20 segments = result; 21 } 22 23 bool queryRange(int left, int right) { 24 if(segments.size() == 0 || left < segments[0].first){ 25 return false; 26 } 27 int start = 0; 28 int end = segments.size()-1; 29 while(start < end){ 30 int pivot = start+(end-start+1)/2; 31 if(segments[pivot].first > left) 32 end = pivot-1; 33 else 34 start = pivot; 35 } 36 return segments[start].second >= right; 37 } 38 39 void removeRange(int left, int right) { 40 vector<pair<int,int>> result; 41 for(int i = 0;i != segments.size();++i){ 42 if(segments[i].second <= left || segments[i].first >= right) 43 result.push_back(segments[i]); 44 else { 45 if(segments[i].first < left) 46 result.push_back(make_pair(segments[i].first,left)); 47 if(segments[i].second > right) 48 result.push_back(make_pair(right,segments[i].second)); 49 } 50 } 51 segments = result; 52 } 53 private: 54 vector<pair<int,int>> segments; 55 }; 56 57 /** 58 * Your RangeModule object will be instantiated and called as such: 59 * RangeModule obj = new RangeModule(); 60 * obj.addRange(left,right); 61 * bool param_2 = obj.queryRange(left,right); 62 * obj.removeRange(left,right); 63 */