# 732. My Calendar III

[ **732. My Calendar III**](https://leetcode.com/problems/my-calendar-iii/description/)

Implement a `MyCalendarThree` class to store your events. A new event can **always** be added.

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`.

A K-booking happens when **K** events have some non-empty intersection (ie., there is some time that is common to all K events.)

For each call to the method `MyCalendar.book`, return an integer `K` representing the largest integer such that there exists a `K`-booking in the calendar. Your class will be called like this: `MyCalendarThree cal = new MyCalendarThree();MyCalendarThree.book(start, end)`

**Example 1:**

```
MyCalendarThree();
MyCalendarThree.book(10, 20); // returns 1
MyCalendarThree.book(50, 60); // returns 1
MyCalendarThree.book(10, 40); // returns 2
MyCalendarThree.book(5, 15); // returns 3
MyCalendarThree.book(5, 10); // returns 3
MyCalendarThree.book(25, 55); // returns 3
Explanation: 
The first two events can be booked and are disjoint, so the maximum K-booking is a 1-booking.
The third event [10, 40) intersects the first event, and the maximum K-booking is a 2-booking.
The remaining events cause the maximum K-booking to be only a 3-booking.
Note that the last event locally causes a 2-booking, but the answer is still 3 because
eg. [10, 20), [10, 40), and [5, 15) are still triple booked.
```

**Note:**

The number of calls to `MyCalendarThree.book` per test case will be at most `400`.

In calls to `MyCalendarThree.book(start, end)`, `start` and `end` are integers in the range `[0, 10^9]`.

***My Solutions:***

题意是对于每次插入新事件，求当前总体最大的重叠事件的个数。 大致思路就是每出现一个起点就代表有一个新的线段，而一个终点的出现就意味着有一条线段结束。

用一个treemap储存每个start和end的个数，map key是时间点，value是出现的次数，如果是start出现，+1，如果是end出现-1。比如

```
MyCalendarThree.book(10, 20); // returns 1，map里有【10，1】和【20，-1】
MyCalendarThree.book(50, 60); // returns 1，map里有【10，1】，【20，-1】，【50，1】，【60，-1】】
MyCalendarThree.book(10, 40); // returns 2，map里有【10，2】，【20，-1】，【40，-1】，【50，1】，【60，-1】
MyCalendarThree.book(5, 15); // returns 3，map里有【5，1】，【10，2】，【15，-1】，【20，-1】，【40，-1】，【50，1】，【60，-1】
MyCalendarThree.book(5, 10); // returns 3， map里有【5，2】，【10，1】，【15，-1】，【20，-1】，【40，-1】，【50，1】，【60，-1】
MyCalendarThree.book(25, 55); // returns 3
```

treemap会自动按照key排序，因此iterate map时，也是按照时间从小到大遍历。在线段结束之前（到达下一个点之前），overlap所达到的最大值就是线段重叠的条数。

```java
class MyCalendarThree {

    TreeMap<Integer, Integer> calendar;
    
    public MyCalendarThree() {
        calendar = new TreeMap();
    }
    
    public int book(int start, int end) {
        // start上的数，value+1
        calendar.put(start, calendar.getOrDefault(start, 0) + 1);
        // end上的数，value-1
        calendar.put(end, calendar.getOrDefault(end, 0) - 1);
        
        int ans = 0, overlap = 0;
        for (int i : calendar.values()) {
            overlap += i; // 代表在某一个点，重叠的个数
            if (overlap > ans) ans = overlap;
        }
        return ans;
        
    }
}
```

比如

```
MyCalendarThree.book(10, 20); // returns 1，map里有【10，1】和【20，-1】
MyCalendarThree.book(50, 60); // returns 1，map里有【10，1】，【20，-1】，【50，1】，【60，-1】】
MyCalendarThree.book(55, 65); // returns 2，map里有【10，1】，【20，-1】，【50，1】，【55，1】，【60，-1】，【65，-1】】
```
