Search lands in PR-5.1 (Pagefind).

How-to Intermediate

Chapter 2 Updated

My Calendar II

Two layers: all bookings + known double-booked regions.

  • Full 5m
  • Revision 2m
  • Flow 1m

Problem Statement

Design a calendar class supporting book(start, end) that allows double booking but rejects any triple booking. Each call returns true if the event was added, false otherwise.

Input

Sequential calls to book(start, end). Events are half-open [start, end).

Example call sequence
book(10, 20)
book(50, 60)
book(10, 40)
book(5, 15)
book(5, 10)
book(25, 55)

Output

Each call returns true (added) or false (rejected because the third concurrent booking would cause a triple).

Expected returns
true     # [10,20) — first event
true     # [50,60) — no conflict
true     # [10,40) — doubles [10,20)
false    # [5,15)  — would triple [10,15)
true     # [5,10)  — touches but doesn't overlap
true     # [25,55) — doubles [50,55), still no triple

Constraints

  • 0 ≤ start < end ≤ 10⁹
  • At most 1000 calls to book.

Intuition

Maintain two lists:

  • bookings — every accepted event.
  • overlaps — the regions where exactly two events already overlap.

For each new event:

  1. If it intersects any region in overlaps → that would be a third overlap → reject.
  2. Otherwise, for every existing booking it overlaps, record the intersection region in overlaps.
  3. Add the new event to bookings.
Two-layer tracking
       bookings layer:   [══════════]       [══════════]
       overlaps layer:        [═════]
                              ↑ two events already share this region
       new event:         [═══════]
                              ↑ would land inside an overlap → REJECT

Solution

my_calendar_ii.py
class MyCalendarTwo:
    def __init__(self):
        self.bookings = []
        self.overlaps = []  # double-booked regions
 
    def book(self, start: int, end: int) -> bool:
        # Check against triple booking
        for os, oe in self.overlaps:
            if start < oe and end > os:
                return False
 
        # Record new double-bookings
        for bs, be in self.bookings:
            if start < be and end > bs:
                self.overlaps.append((max(start, bs), min(end, be)))
 
        self.bookings.append((start, end))
        return True

Complexity

MetricValueReason
Time (per call)O(n)Scans both bookings and overlaps
SpaceO(n)Two-layer tracking — bookings + overlap regions

Edge Case Thinking

ScenarioHandling
First bookingoverlaps and bookings both empty → accepted, nothing recorded in overlaps.
Double booking (exactly 2)Accepted; new region added to overlaps.
Triple booking attemptRejected at the first loop — no state mutated.
Touching boundary [10,20) & [20,30)20 < 20 is false → not treated as overlap; no double/triple created.
Same interval booked twiceSecond call accepted (double); third call would be rejected.

Comments

Comments are disabled in this environment. Set PUBLIC_GISCUS_REPO, PUBLIC_GISCUS_REPO_ID, and PUBLIC_GISCUS_CATEGORY_ID to enable.