ETH官方钱包

前往
大廳
主題

LeetCode - 729. My Calendar I 解題心得

Not In My Back Yard | 2021-08-21 00:00:09 | 巴幣 0 | 人氣 357

題目連結:


題目意譯:
你正實作一個可用的日曆程式。我們可以新增一個事件,如果新增該事件後不會造成雙重預約。

一個雙重預約發生於兩個事件有著非空之交集(即有些時刻同存於兩個事件之中)

一個事件可以表為一數對 start 和 end 其代表著一個預約片段於半開區間 [start, end) ,即 x 值之範圍其滿足 start ≦ x < end 。

實作類別 MyCalendar:
MyCalendar() 初始化一個日曆之物件。
boolean book(int start, int end) 回傳真(True)如果該事件可被成功地加入到日曆之中而不會造成雙重預約;反之,回傳假(False)且不把該事件加入到日曆中。

限制:
0 ≦ start < end ≦ 10 ^ 9
最多有 1000 次呼叫為 book 。



範例測資:
輸入
["MyCalendar", "book", "book", "book"]
[[], [10, 20], [15, 25], [20, 30]]
輸出
[null, true, false, true]
解釋
MyCalendar myCalendar = new MyCalendar();
myCalendar.book(10, 20); // 回傳真
myCalendar.book(15, 25); // 回傳假,它無法預約因為時間 15 已經被另一個事件預約了。
myCalendar.book(20, 30); // 回傳真,該事件可預約,因為第一個事件佔有小於 20 的所有時間點,但不包含 20 本身。


解題思維:
利用一個平衡的二元搜尋樹 T(Balanced Binary Search Tree,如 C++ 的 map 和 set 容器)來儲存預約成功之事件的時間區間。

對於每個事件 [start, end),如果 T 為空,則理所當然地可以將此事件加入。

如果 T 非空,則去 T 中找到第一個小於其左端點(事件開始)的事件。如果有找到則判斷 end 是否 > 該事件的左端點。如果是則代表此事件加入後會與找到的事件重疊,因此無法將此事件 [start, end) 加入。

如果沒有與該事件重疊或是根本就找不到這樣子事件,則檢查找到的事件之前一個(對於找不到的情況,則為左端點最靠右的事件)事件,檢查其右端點是否 > start 。如果是則代表 [start, end) 這個事件會與該事件衝突,所以也不能加入。

如果以上檢查都通過,則代表 [start, end) 的加入不會與任何事件衝突,因此可以將其加入於 T 之中。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作