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
.
思路: start, left, end, right; 用treemap来存interval, <start, end> key是start,value是end,这样key就是自动sorted。找到left的下限和right的下限,分别进行判断;注意要subMap需要clean;subMap这个API需要会用;floorKey last greater or equal than key;
所以query的时候,需要用start来判断,intervals.get(start) >= right;
class RangeModule {
TreeMap<Integer, Integer> intervals;
public RangeModule() {
intervals = new TreeMap<>();
}
// add [left, right);
public void addRange(int left, int right) {
if(right <= left) {
return;
}
Integer start = intervals.floorKey(left);
Integer end = intervals.floorKey(right);
if(start != null && intervals.get(start) >= left) {
left = start;
}
if(end != null && intervals.get(end) > right) {
right = intervals.get(end);
}
intervals.put(left, right);
// clean 中间的 keyset
intervals.subMap(left, false, right, true).clear();
}
// [left, right);
public boolean queryRange(int left, int right) {
Integer start = intervals.floorKey(left);
if(start == null) {
return false;
}
return intervals.get(start) >= right;
}
// [left, right)
public void removeRange(int left, int right) {
if(right <= left) {
return;
}
Integer start = intervals.floorKey(left);
Integer end = intervals.floorKey(right);
if(end != null && intervals.get(end) > right) {
intervals.put(right, intervals.get(end));
}
if(start != null && intervals.get(start) > left) {
intervals.put(start, left);
}
// clean 中间的key set
intervals.subMap(left, true, right, false).clear();
}
}
/**
* Your RangeModule object will be instantiated and called as such:
* RangeModule obj = new RangeModule();
* obj.addRange(left,right);
* boolean param_2 = obj.queryRange(left,right);
* obj.removeRange(left,right);
*/