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 numbers
left <= x < right
.
0 < left < right < 10^9
in all calls to
addRange, queryRange, removeRange
.The total number of calls to
addRange
in a single test case is at most
1000
.The total number of calls to
queryRange
in a single test case is at most
5000
.The total number of calls to
removeRange
in a single test case is at most
1000
.
题目理解:实现实数区间的添加、删除和查找函数
解题思路:区间这种题目,目前遇到了好几个,大致的经验是,使用TreeMap存储区间,key是区间左边界,value是区间右边界。添加区间[left, right]的时候,使用floorKey函数找到小于left的最大key,处理与这个区间的重叠;然后遍历left <= key < = right的所有key,处理与这些区间的重叠。删除区间的时候思路类似。查找区间的之后,使用floorKey找到小于left的最大key,然后根据right和value的关系判断。
import java.util.*;
class RangeModule {
TreeMap<Integer, Integer> map;
public RangeModule() {
map = new TreeMap<Integer, Integer>();
}
public void addRange(int left, int right) {
//往前遍历一个
if(map.floorKey(left) != null){
int start = map.floorKey(left), end = map.get(start);
if(end >= right)
return;
if(end >= left){
map.remove(start);
left = start;
}
}
//遍历left与right之间的全部区间
SortedMap<Integer, Integer> submap = map.subMap(left, true, right, true);
List<Integer> list = new ArrayList<Integer>();
for(int key : submap.keySet())
list.add(key);
for(int start : list){
int end = map.get(start);
map.remove(start);
right = Math.max(right, end);
}
map.put(left, right);
}
public boolean queryRange(int left, int right) {
if(map.floorKey(left) == null)
return false;
int start = map.floorKey(left);
//System.out.println(left + " " + right + " " + start + " " + map.get(start));
if(map.get(start) < right)
return false;
return true;
}
public void removeRange(int left, int right) {
//往前遍历一个
if(map.floorKey(left) != null){
int start = map.floorKey(left), end = map.get(start);
if(end > left){
map.put(start, left);
map.put(left, end);
}
}
//遍历left与right之间全部的区间
SortedMap<Integer, Integer> submap = map.subMap(left, true, right, true);
List<Integer> list = new ArrayList<Integer>();
for(int key : submap.keySet())
list.add(key);
for(int start : list){
if(map.get(start) <= right)
map.remove(start);
else{
map.put(right, map.get(start));
map.remove(start);
}
}
}
}