前往
大廳
主題

LeetCode - 2402. Meeting Rooms III 解題心得

Not In My Back Yard | 2023-07-31 12:00:27 | 巴幣 0 | 人氣 237

題目連結:


題目意譯:
你被給定一個整數 n。代表現在有編號為 0 到 n - 1 的 n 間房間。

你被給定一個二維整數陣列 meetings,其中 meetings[starti, endi] 代表著有一場會議將會在半閉時間區間 [starti, endi) 的時候舉辦。所有 starti 之數值彼此相異。
 
會議將會根據以下方式分配到各個房間:
每場會議將會舉辦於有著最小編號的未佔用房間。
如果現在沒有空房間,則該會議將會被延期直到有房間空出來為止。被延後的會議之持續時間應與原本相同。
當有一間房變為未佔用的狀態,有著最早開始時間的會議應被提供該房間。

回傳有最多場會議舉行的房間為何。如果有多間房間,則回傳編號最小者。

一個半閉區間 [a, b) 為一個介於 a 到 b 之間,其中端點 a 有包含在內,但 b 則無。

限制:
1 ≦ n ≦ 100
1 ≦ meetings.length ≦ 10 ^ 5
meetings[i].length == 2
0 ≦ starti < endi ≦ 5 × 10 ^ 5
所有 starti 之數值彼此相異。



範例測資:
範例 1:
輸入: n = 2, meetings = [[0,10],[1,5],[2,7],[3,4]]
輸出: 0
解釋:
- 在時間點 0,兩個房間都沒被佔用。第一場會議舉行於房間 0。
- 在時間點 1,只有房間 1 沒被佔用。第二場會議舉行於房間 1。
- 在時間點 2,兩個房間都被佔用了。第三場會議被延期。
- 在時間點 3,兩個房間都被佔用了。第四場會議被延期。
- 在時間點 5,位於房間 1 的會議開完了。第三場會議舉行於房間 1,其時間段為 [5,10)。
- 在時間點 10,位於兩個房間的會議都開完了。第四場會議舉行於房間 0,其時間段為 [10,11)。
房間 0 和房間 1 都舉行了兩場會議,所以我們回傳 0。

範例 2:
輸入: n = 3, meetings = [[1,20],[2,10],[3,5],[4,9],[6,8]]
輸出: 1
解釋:
- 在時間點 1,三間房間都沒被佔用。第一場會議將舉行於房間 0。
- 在時間點 2,房間 1 和 2 都沒被佔用。第二場會議將舉行於房間 1。
- 在時間點 3,只有房間 2 沒有被佔用。第三場會議將舉行於房間 2。
- 在時間點 4,所有房間都被佔用了。第四場會議被延期。
- 在時間點 5,位於房間 2 的會議開完了。第四場會議舉行於房間 2,其時間段為 [5,10)。
- 在時間點 6,所有房間都被佔用了。第五場會議被延期。
- 在時間點 10,位於房間 1 和 2 的會議都開完了。第五場會議舉行於房間 1,其時間段為 [10,12)。
房間 1 舉行了 1 場會議,而房間 1 和 2 各舉行了 2 場,所以我們回傳 1。


解題思維:
模擬即可。

所以我們需要什麼?很明顯的,我們會先需要記錄哪些房間目前有被佔用、目前已經開了多少場會議。

此外,為了決定之後哪些會議如果要延後時程的話需要延後到哪個時刻,我們需要記錄所有現在正在開的會議之結束時間。而可以看到先結束的會被後來的會議取代,因此這邊記錄用的資料結構需要動態地維護所有結束時間中的最小值,而優先佇列(Priority Queue)可以勝任這個任務。

以上,稱記錄佔用情況的陣列為 U、已經開的會議數量之陣列為 C、維護結束時間最小值(連同房間編號)的優先佇列為 PQ。



接著是對資料本身進行處理。根據題目敘述可以看到我們應當按照著開始時間的早晚來安排房間(越早開始的越早分配到房間)。而題目沒有保證給定的會議時間們將會依照開始時間來排序,因此我們需要自行依據開始時間由早到晚排序。

接著掃過排序後的每一場會議:
    假設現在看到的是會議 m,其時間區間為 [L, R)。而如果現在可以看到如果 PQ 中的最小值(最早結束的會議)是先於 m 之開始,即「最早的結束時間」 ≦ L,則 m 將會開在這個結束掉的會議之房間。其中判斷條件有「=」之情況是因為會議的時間是半閉區間,因此結束時間本身可以塞另一個會議的開始;又或是 PQ 中的元素數量以及到達 n 了,也就是所有房間都被佔用了,因此必須把最早結束的會議之房間空出來。

    如果上述情況只有後者的條件有被滿足(全房間佔滿),則代表最早結束的時間(稱其為 X)是大於 L 的。因此我們需要額外把 m 的時間區間調整至 [X, X + (R - L))。

    不管上述情況有無發生,總之現在的階段必定有房間可以用(記得前面條件符合要把 U 的對應位置清掉,以代表該房間空了)。因此我們由編號 0 掃到編號 n - 1,看哪間房間可以用即可(用陣列 U 的數值判斷)。假設找到的是房間 i,則我們需要把 C[i] 加 1,代表房間 i 多開了一場會議。接著把 m 的結束時間(可能是原本的 R,又或是 X + (R - L),取決於前面的條件有無符合)以及使用的房間編號放到 PQ 中。

重複以上步驟直到掃過所有房間為止。最後只要掃過一次陣列 C,看哪個房間的會議最多即可。




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

創作回應

相關創作

更多創作