Range Module

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);
    		}
    	}
    }
}


猜你喜欢

转载自blog.csdn.net/m0_37889928/article/details/80651691