LeetCode 731. My Calendar II

Problem Description: 

Implement a MyCalendarTwo class to store your events. A new event can be added if adding the event will not cause a triple booking.

Your class will have one method, book(int start, int end). Formally, this represents a booking on the half open interval [start, end), the range of real numbers x such that start <= x < end.

triple booking happens when threeevents have some non-empty intersection (ie., there is some time that is common to all 3 events.)

For each call to the method MyCalendar.book, return true if the event can be added to the calendar successfully without causing a triplebooking. Otherwise, return false and do not add the event to the calendar.

Your class will be called like this: MyCalendar cal = new MyCalendar();MyCalendar.book(start, end)

解题思路I:

使用Java的TreeMap<Integer, Integer>数据结构,每次book(int start, int end)时,在开始位置的值+1,结束位置的值-1。

class MyCalendarTwo {
    
    TreeMap<Integer, Integer> map;
    public MyCalendarTwo() {
        map = new TreeMap<>();
    }
    
    public boolean book(int start, int end) {
        map.put(start, map.getOrDefault(start, 0) + 1);
        map.put(end, map.getOrDefault(end, 0) - 1);
        int count = 0;
        for(Map.Entry<Integer, Integer> entry : map.entrySet()) {
            count += entry.getValue();
            if(count == 3) {
                map.put(start, map.get(start) - 1);
                map.put(end, map.get(end) + 1);
                return false;
            }
        }
        return true;
    }
}

当其中某段位置的值达到3,则表示已经triplebook,需要撤销此次添加,并返回false。

这个解法比较巧妙,但是时间上并不优,treemap是树形的结构,对treemap的操作的时间复杂度为O(log2n)。每次book的时间复杂度为O(nlogn).

另一种解法则是按照提示,用两个list。一个记录所有book,另一个记录已经有的冲突。若新的插入与已有冲突没有冲突,则可以插入到末尾。一种比较简单的写法如下。

class MyCalendarTwo {
    
    class Interval {
        int start, end;
        public Interval() {}
        public Interval(int start, int end) {
            this.start = start;
            this.end = end;
        }
    }
    List<Interval> list;
    List<Interval> overlaps;
    public MyCalendarTwo() {
        list = new ArrayList<>();
        overlaps = new ArrayList<>();
    }
    public boolean book(int start, int end) {
        //check the overlaps
        for(Interval interval : overlaps) {
            int newStart = Math.max(start, interval.start);
            int newEnd = Math.min(end, interval.end);
            if(newStart < newEnd) return false;
        }
        
        for(Interval interval : list) {
            int newStart = Math.max(start, interval.start);
            int newEnd = Math.min(end, interval.end);
            if(newStart < newEnd) {
                overlaps.add(new Interval(newStart, newEnd));
            }
        }
        list.add(new Interval(start, end));
        return true;
    }
    
}

每次book需要遍历一次list和overlaps,线性复杂度O(n)。

猜你喜欢

转载自www.cnblogs.com/rookielet/p/10543599.html