前往
大廳
主題

LeetCode - 1656. Design an Ordered Stream 解題心得

Not In My Back Yard | 2023-03-01 12:00:01 | 巴幣 0 | 人氣 287

題目連結:


題目意譯:
現在有一串 n 個 (idKey, value) 數對以隨機順序抵達,其中 idKey 為一個介於 1 到 n 之間的整數,而 value 為一字串。任意兩對的 id 都不同。

請設計一個串流,其將在每次插入後藉由回傳一個區塊(列表)來回傳依據各自的 ID 遞增排列而排序後的 value 們。這些區塊串接後應得到 value 們排序後的列表。

實作類別 OrderedStream:
OrderedStream(int n) 建構可以容納 n 個數值的串流。
String[] insert(int idKey, String value) 將 (idKey, value) 數對插入進串流之中,並回傳在已被插入的 value 們中最大可能會依照排序後之順序出現的區塊。

(譯注:
原文的敘述令人混淆,所以我翻譯後等於沒翻。在此說聲抱歉。

總而言之,題目想要問的是類似網路通訊中「封包」(Packets)的概念。假設現在你有編號 1 ~ n 的封包,但是它們不一定會依照順序抵達目的地。

而你要開始解碼封包的話,勢必得從編號 1 開始(因為編號 1 有著標頭檔(Headers)用以表示整個訊息的大小等資訊)。所以你就算可能已經收到了編號 2 ~ 4 、 7 、 11 的封包,你也不能先去對這些封包解碼。

而一旦編號 1 抵達後(假設你依舊只有 2 ~ 4 、 7 和 11),你便可以一次把編號 1 ~ 4 的封包全部解碼。因此接下來你要等的封包編號為 5。

因此題目的意思便是:假設現在你等的是封包編號 X。而現在來了編號 Y 的封包,則此時此刻你「最多」可以一次去解碼多少封包。

以上面的例子而言就是當 X = Y = 1 時,我們「最多」可以一次解掉 1 ~ 4(因為 2 ~ 4 已於先前抵達,不過 5 還沒)。所以接著要等 X = 5,且回傳的內容為編號 1 ~ 4 的內容(也就是 value 們)。

而如果 X = 1 、 Y = 5,則你什麼封包都解不了。所以「最多」是 0 個,因此回傳的內容為空列表。

以上。)


限制:
1 ≦ n ≦ 1000
1 ≦ id ≦ n
value.length == 5
value 只由小寫字母組成。
每次呼叫 insert 有著的 id 彼此相異。
insert 恰好會被呼叫 n 次。



範例測資:
Example:
輸入
["OrderedStream", "insert", "insert", "insert", "insert", "insert"]
[[5], [3, "ccccc"], [1, "aaaaa"], [2, "bbbbb"], [5, "eeeee"], [4, "ddddd"]]
輸出
[null, [], ["aaaaa"], ["bbbbb", "ccccc"], [], ["ddddd", "eeeee"]]
解釋
// 注意到 value 們根據 ID 排序為 ["aaaaa", "bbbbb", "ccccc", "ddddd", "eeeee"]。
OrderedStream os = new OrderedStream(5);
os.insert(3, "ccccc"); // 插入 (3, "ccccc"),回傳 []。
os.insert(1, "aaaaa"); // 插入 (1, "aaaaa"),回傳 ["aaaaa"]。
os.insert(2, "bbbbb"); // 插入 (2, "bbbbb"),回傳 ["bbbbb", "ccccc"]。
os.insert(5, "eeeee"); // 插入 (5, "eeeee"),回傳 []。
os.insert(4, "ddddd"); // 插入 (4, "ddddd"),回傳 ["ddddd", "eeeee"]。
// 將所有回傳的區塊串接在一起:
// [] + ["aaaaa"] + ["bbbbb", "ccccc"] + [] + ["ddddd", "eeeee"] = ["aaaaa", "bbbbb", "ccccc", "ddddd", "eeeee"]
// 得到的順序與上述提及的順序相同。


解題思維:
按照我對題目敘述的重新詮釋去照著做就可以了。為此,我們可以在建構子 OrderedStream(int n) 被呼叫時,生成一個長度 n + 2 的字串陣列 P(P[0] 和 P[n + 1] 只是把 1 ~ n 的東西包起來,避免出界等問題)。並用一個變數 x 來表示現在等待的「封包」編號。

一開始陣列中存的值都是空字串(表示沒有東西抵達)。而當 insert(int idKey, String value) 被呼叫時,則將 P[idKey] 之值設為 value。

而此時如果 x 恰好等於 idKey,則 P[x] 、 P[x + 1] 、……、 P[x + k] 之內容放到一列表中並回傳,其中 P[x] 、 P[x + 1] 、……、 P[x + k] 的內容皆為非空字串(也就是 P[x + k + 1] 之值「目前」是空字串)。接著把 x 之值設為 x + k + 1,代表下一個要等待的封包編號。

如果呼叫時,x 不等於 idKey,則直接回傳一個空列表即可。




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

創作回應

相關創作

更多創作