Skip to content

Commit c7e3196

Browse files
medium v good BST, array, TreeMap array class try
729. My Calendar I Solved Medium Topics Companies Hint 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 start and end that represents a booking on the half-open interval [start, end), the range of real numbers x such that start <= x < end. Implement the MyCalendar class: MyCalendar() Initializes the calendar object. boolean book(int start, int end) 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. Example 1: 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 <= 109 At most 1000 calls will be made to book. Seen this question in a real interview before? 1/5 Yes No Accepted 392K Submissions 671.8K Acceptance Rate 58.4% Topics Companies Hint 1 Store the events as a sorted list of intervals. If none of the events conflict, then the new event can be added.
1 parent 6abb972 commit c7e3196

File tree

1 file changed

+286
-0
lines changed

1 file changed

+286
-0
lines changed

My-calender-1.java

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
class MyCalendar {
2+
3+
class Node {
4+
int start;
5+
int end;
6+
Node left,right;
7+
8+
public Node(int start,int end){
9+
this.start = start;
10+
this.end = end;
11+
}
12+
}
13+
14+
Node root;
15+
16+
public MyCalendar() {
17+
18+
}
19+
20+
public boolean book(int start, int end) {
21+
if(root == null){
22+
root = new Node(start,end);
23+
return true;
24+
}
25+
Node curr = root;
26+
while(curr != null){
27+
if(end <= curr.start){
28+
if(curr.left == null){
29+
curr.left = new Node(start,end);
30+
return true;
31+
}
32+
curr = curr.left;
33+
}
34+
else if(start >= curr.end){
35+
if(curr.right == null){
36+
curr.right = new Node(start,end);
37+
return true;
38+
}
39+
curr = curr.right;
40+
}
41+
else return false;
42+
}
43+
return false;
44+
}
45+
}
46+
47+
48+
49+
/**
50+
51+
This implementation of `MyCalendar` uses a binary search tree (BST) to efficiently manage the booking of events without overlapping. Each node in the tree represents an event, with `start` and `end` representing the start and end times of that event.
52+
53+
### Explanation:
54+
55+
#### 1. **Node Class**:
56+
```java
57+
class Node {
58+
int start;
59+
int end;
60+
Node left, right;
61+
62+
public Node(int start, int end) {
63+
this.start = start;
64+
this.end = end;
65+
}
66+
}
67+
```
68+
- Each node stores the `start` and `end` times of an event.
69+
- `left` points to events that end before this event starts.
70+
- `right` points to events that start after this event ends.
71+
72+
#### 2. **Root Initialization**:
73+
```java
74+
Node root;
75+
```
76+
- The tree has a `root` node, which is initialized as `null` in the constructor.
77+
78+
```java
79+
public MyCalendar() {}
80+
```
81+
- The constructor initializes the `root` of the binary tree as `null` because initially, there are no booked events.
82+
83+
#### 3. **book Method**:
84+
The `book` method attempts to add a new event `[start, end)` to the calendar while ensuring there is no overlap with any existing events.
85+
86+
```java
87+
public boolean book(int start, int end) {
88+
if (root == null) {
89+
root = new Node(start, end);
90+
return true;
91+
}
92+
```
93+
- If the tree is empty (`root == null`), the event is added as the root node, and the method returns `true`.
94+
95+
#### 4. **Traversing the Tree**:
96+
The method then traverses the tree to find the correct position for the new event, ensuring no overlap with any existing event.
97+
98+
```java
99+
Node curr = root;
100+
while (curr != null) {
101+
```
102+
- The method starts at the root and iteratively traverses down the tree.
103+
104+
- **If the new event ends before the current event starts**:
105+
```java
106+
if (end <= curr.start) {
107+
if (curr.left == null) {
108+
curr.left = new Node(start, end);
109+
return true;
110+
}
111+
curr = curr.left;
112+
}
113+
```
114+
- This means the new event should be placed in the left subtree (since there is no overlap).
115+
- If the left child is `null`, the new event is inserted as the left child.
116+
- If not, the traversal continues to the left child.
117+
118+
- **If the new event starts after the current event ends**:
119+
```java
120+
else if (start >= curr.end) {
121+
if (curr.right == null) {
122+
curr.right = new Node(start, end);
123+
return true;
124+
}
125+
curr = curr.right;
126+
}
127+
```
128+
- This means the new event should be placed in the right subtree (since there is no overlap).
129+
- If the right child is `null`, the new event is inserted as the right child.
130+
- If not, the traversal continues to the right child.
131+
132+
- **If the new event overlaps with the current event**:
133+
```java
134+
else return false;
135+
```
136+
- If neither condition holds (i.e., `end > curr.start` and `start < curr.end`), the new event overlaps with an existing one, so the booking fails, and `false` is returned.
137+
138+
#### 5. **Edge Cases**:
139+
- If the new event is disjoint from all existing events, it will be inserted in the appropriate position in the BST, either as a left or right child.
140+
- The tree is traversed using a `while` loop, ensuring that the insertion or conflict detection happens efficiently.
141+
142+
### Summary:
143+
- This solution uses a binary search tree (`BST`) to store events, where each node represents an event with a `start` and `end` time.
144+
- The `book` method tries to insert a new event, ensuring no overlap by checking the relative positions of the new event against existing ones.
145+
- Time complexity for insertion and search is on average `O(log n)` for balanced trees but can degrade to `O(n)` in the worst case for unbalanced trees. */
146+
147+
148+
149+
150+
151+
152+
153+
154+
155+
156+
157+
158+
159+
160+
161+
//option2
162+
class MyCalendar {
163+
TreeMap<Integer, Integer> calendar;
164+
165+
MyCalendar() {
166+
calendar = new TreeMap();
167+
}
168+
169+
public boolean book(int start, int end) {
170+
Integer prev = calendar.floorKey(start),
171+
next = calendar.ceilingKey(start);
172+
if ((prev == null || calendar.get(prev) <= start) &&
173+
(next == null || end <= next)) {
174+
calendar.put(start, end);
175+
return true;
176+
}
177+
return false;
178+
}
179+
}
180+
/**
181+
The `MyCalendar` class implements a booking system that allows users to book events, ensuring that no two events overlap. It uses a `TreeMap` to store and manage the events, where the keys represent the start times and the values represent the end times of the booked events.
182+
183+
Here’s a detailed breakdown of how the class works:
184+
185+
### 1. **TreeMap Initialization**:
186+
```java
187+
TreeMap<Integer, Integer> calendar;
188+
```
189+
- `TreeMap` is a data structure that stores key-value pairs and automatically keeps the keys in sorted order.
190+
- In this case, the keys are event start times, and the values are the corresponding end times.
191+
192+
```java
193+
calendar = new TreeMap();
194+
```
195+
- The constructor initializes the `TreeMap` to manage the events.
196+
197+
### 2. **`book` Method**:
198+
This method checks if an event can be booked without overlapping any existing events.
199+
200+
```java
201+
public boolean book(int start, int end)
202+
```
203+
- **Parameters**:
204+
- `start`: The start time of the new event.
205+
- `end`: The end time of the new event (exclusive, meaning the event ends right before this time).
206+
207+
- **Logic**:
208+
- The method checks if there is any overlap with the previously booked event (`prev`) or the next booked event (`next`).
209+
210+
```java
211+
Integer prev = calendar.floorKey(start),
212+
next = calendar.ceilingKey(start);
213+
```
214+
- `prev`: The `floorKey` returns the largest key (start time) that is less than or equal to `start`. This represents the previous event's start time.
215+
- `next`: The `ceilingKey` returns the smallest key (start time) that is greater than or equal to `start`. This represents the next event's start time.
216+
217+
Now, the method checks two conditions:
218+
```java
219+
if ((prev == null || calendar.get(prev) <= start) && (next == null || end <= next))
220+
```
221+
- **Condition 1**: `(prev == null || calendar.get(prev) <= start)`
222+
- This checks whether there is no previous event (`prev == null`) or the previous event ends before or at the new event’s start time (`calendar.get(prev) <= start`).
223+
224+
- **Condition 2**: `(next == null || end <= next)`
225+
- This checks whether there is no next event (`next == null`) or the new event ends before the next event starts (`end <= next`).
226+
227+
If both conditions are satisfied (i.e., no overlap with either previous or next events), the event is added to the `calendar`:
228+
```java
229+
calendar.put(start, end);
230+
return true;
231+
```
232+
233+
If there is an overlap, the method returns `false`.
234+
235+
### 3. **Example**:
236+
```java
237+
MyCalendar obj = new MyCalendar();
238+
boolean result = obj.book(10, 20); // This will return true if the event [10, 20) can be booked.
239+
```
240+
241+
### Summary:
242+
- The `TreeMap` structure ensures that events are stored in a sorted manner by start time.
243+
- The `book` method checks if the new event overlaps with the nearest previous and next events using `floorKey` and `ceilingKey`.
244+
- If there is no overlap, the event is booked (added to the `TreeMap`), and the method returns `true`. If there is an overlap, it returns `false`.
245+
246+
*/
247+
248+
249+
250+
/**
251+
* Your MyCalendar object will be instantiated and called as such:
252+
* MyCalendar obj = new MyCalendar();
253+
* boolean param_1 = obj.book(start,end);
254+
*/
255+
256+
257+
258+
259+
// option3 -BRUTE FORCE
260+
class MyCalendar {
261+
List<int[]> calender;
262+
public MyCalendar() {
263+
calender=new ArrayList<>();
264+
}
265+
public boolean book(int start, int end) {
266+
for(int[] slot:calender){
267+
if(end>slot[0] && start<slot[1]){
268+
return false;
269+
}
270+
}
271+
calender.add(new int[]{start,end});
272+
return true;
273+
}
274+
}
275+
276+
/**
277+
* Your MyCalendar object will be instantiated and called as such:
278+
* MyCalendar obj = new MyCalendar();
279+
* boolean param_1 = obj.book(start,end);
280+
*/
281+
282+
/**
283+
* Your MyCalendar object will be instantiated and called as such:
284+
* MyCalendar obj = new MyCalendar();
285+
* boolean param_1 = obj.book(start,end);
286+
*/

0 commit comments

Comments
 (0)