Problem
LeetCode 732 — My Calendar III
Implement MyCalendarThree which tracks calendar bookings. Each book(start, end) adds an event on [start, end) (half-open interval). Return the maximum number of events that overlap at any single point in time after each booking.
Example
book(10, 20) → 1
book(50, 60) → 1
book(10, 40) → 2 (overlap on [10, 20))
book(5, 15) → 3 (overlap on [10, 15))
Timeline after all four bookings:
5 10 15 20 40 50 60
[-----) (book 4: [5,15))
[-----) (book 1: [10,20))
[-------------------) (book 3: [10,40))
[-----) (book 2: [50,60))
At [10, 15): events 1, 3, and 4 overlap → peak = 3
Approach — Sweep Line with TreeMap
Each booking adds +1 at start and -1 at end on a timeline — same idea as Meeting Rooms II’s sweep, but you track the peak overlap instead of the current count at one moment.
timeline[start] += 1
timeline[end] -= 1
sweep keys in sorted order:
active += timeline[t]
max = max(max, active)
Half-open intervals [start, end) mean the -1 at end correctly removes the event before time end is counted as active.
Why TreeMap? Times go up to 10⁹, but only ~400 bookings — endpoints are sparse. TreeMap keeps sorted event points without a huge array.
Why not increment every minute in [start, end)? Range can be billions wide — marking only boundaries avoids a huge array.
Walkthrough (example order)
After book(10, 20):
timeline: 10:+1, 20:-1 → sweep: active 1 at 10, max = 1
After book(50, 60):
timeline: 10:+1, 20:-1, 50:+1, 60:-1 → max still 1
After book(10, 40):
timeline: 10:+2, 20:-1, 40:-1, 50:+1, 60:-1
sweep: 10→2, 20→1, 40→0, 50→1, 60→0 → max = 2
After book(5, 15):
timeline: 5:+1, 10:+2, 15:-1, 20:-1, 40:-1, 50:+1, 60:-1
sweep: 5→1, 10→3, 15→2, 20→1, 40→0, 50→1, 60→0 → max = 3
At time 10, three events are active: [5,15), [10,20), and [10,40).
Complexity
- Time:
O(k)sweep perbook(), plusO(log k)for each TreeMap update — dominated byO(k)wherek= distinct endpoints so far (≤ ~800 on LC) - Space:
O(k)
maxOverlap is never reset — each book() returns the peak overlap seen across all bookings so far, which matches the problem.
For point update + range query on a dense array, see 18-segment-tree-range-queries.md. Calendar booking is a range add — sweep line fits better here.
Solution
class MyCalendarThree {
private final TreeMap<Integer, Integer> timeline = new TreeMap<>();
private int maxOverlap = 0;
public int book(int start, int end) {
timeline.put(start, timeline.getOrDefault(start, 0) + 1);
timeline.put(end, timeline.getOrDefault(end, 0) - 1);
int active = 0;
for (int delta : timeline.values()) {
active += delta;
maxOverlap = Math.max(maxOverlap, active);
}
return maxOverlap;
}
}
Why It Teaches You Something
Same family as #12 (intervals + time sweep), different question: peak overlap vs greedy scheduling.
| Problem | Sweep tracks |
|---|---|
| My Calendar III (LC 732) | max concurrent events on timeline |
| Meeting Rooms II (LC 253) | min rooms needed (heap variant in #12) |
| Car Pooling (LC 1094) | max passengers on route |
| My Calendar I (LC 729) | boolean overlap check (TreeMap of starts) |
The difference-array-on-endpoints trick is the interview solution here.