> ## Documentation Index
> Fetch the complete documentation index at: https://leetcode-py.wisl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> leetcode-py is a Python LeetCode practice environment generator with one CLI: lcpy. It is not a service or platform.
> Each problem is a directory under leetcode/ with README.md, solution.py, test_solution.py, helpers.py, and playground.ipynb. lcpy gen creates them from JSON templates bundled with the package.
> Examples are backed by tests; copy them verbatim.

# My Calendar I Python Solution with Tests

> Tested Python solution for LeetCode 729 with 14 pytest cases. Generate a practice environment with lcpy.

LeetCode 729, Medium. Topics: Array, Binary Search, Design, Segment Tree, Ordered Set. [View on LeetCode](https://leetcode.com/problems/my-calendar-i/description/).

Generate this problem as a practice environment: tested reference solution, 14 [parametrized pytest cases](/practice/testing), and a playground notebook:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 729   # by problem number
lcpy gen -s my_calendar_i   # by problem name
```

## Problem

You are implementing a program to use as your calendar. We can add a new event if adding the event will not cause a **double booking**.

A **double booking** happens when two events have some non-empty intersection (i.e., some moment is common to both events.).

The event can be represented as a pair of integers `startTime` and `endTime` that represents a booking on the half-open interval `[startTime, endTime)`, the range of real numbers `x` such that `startTime <= x < endTime`.

Implement the `MyCalendar` class:

* `MyCalendar()` Initializes the calendar object.
* `boolean book(int startTime, int endTime)` Returns `true` if the event can be added to the calendar successfully without causing a **double booking**. Otherwise, return `false` and do not add the event to the calendar.

### Examples

```
Input
["MyCalendar", "book", "book", "book"]
[[], [10, 20], [15, 25], [20, 30]]
Output
[null, true, false, true]

Explanation
MyCalendar myCalendar = new MyCalendar();
myCalendar.book(10, 20); // return True
myCalendar.book(15, 25); // return False, It can not be booked because time 15 is already booked by another event.
myCalendar.book(20, 30); // return True, The event can be booked, as the first event takes every time less than 20, but not including 20.
```

### Constraints

* 0 \<= start \< end \<= 10^9
* At most 1000 calls will be made to book.

## Solution

Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/my_calendar_i/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/my_calendar_i/test_solution.py):

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class MyCalendar:
    # Time: O(n) per booking, O(n^2) total for n bookings
    # Space: O(n)
    def __init__(self):
        self.calendar: list[tuple[int, int]] = []

    # Time: O(n) per booking
    # Space: O(1)
    def book(self, start: int, end: int) -> bool:
        for s, e in self.calendar:
            if start < e and end > s:
                return False
        self.calendar.append((start, end))
        return True
```

## Complexity

| Time                                          | Space |
| --------------------------------------------- | ----- |
| O(n) per booking, O(n^2) total for n bookings | O(n)  |

## Tags

[NeetCode All](/catalog/neetcode), [AlgoMaster 75](/catalog/algo-master-75).
