題目連結:
題目意譯:
你被給定一個有著 n 個影片的串流,每個影片被一個介於 1 到 n 之間的相異整數所表示,而你需要將它們「上傳」到伺服器裡。你需要實作一個資料結構,其可以在上傳過程中的不同時機點計算出最長的「已上傳前綴」之長度。
如果所有在範圍 1(含)到 i(含)中的所有影片都被已經上傳到伺服器了,則我們將把 i 視為一個「已上傳前綴」。而最長的已上傳前綴為滿足此定義的最大 i 值。
實作類別 LUPrefix:
LUPrefix(int n) 初始化有著 n 個影片的串流之物件。
void upload(int video) 上傳 video 到伺服器。
int longest() 回傳最長的已上傳前綴之長度。
限制:
1 ≦ n ≦ 10 ^ 5
1 ≦ video ≦ n
所有影片的數值彼此相異。
最多總計呼叫 upload 和 longest 共 2 × 10 ^ 5 次。
至少會呼叫一次 longest。
範例測資:
範例 1:
輸入
["LUPrefix", "upload", "longest", "upload", "longest", "upload", "longest"]
[[4], [3], [], [1], [], [2], []]
輸出
[null, null, 0, null, 1, null, 3]
解釋
LUPrefix server = new LUPrefix(4); // 初始化一個有著 4 個影片的串流。
server.upload(3); // 上傳影片 3。
server.longest(); // 由於影片 1 還未被上傳,也就代表著沒有前綴。
// 所以我們回傳 0。
server.upload(1); // 上傳影片 1。
server.longest(); // 前綴 [1] 是最長的已上傳前綴,所以我們回傳 1。
server.upload(2); // 上傳影片 2。
server.longest(); // 前綴 [1,2,3] 是最長的已上傳前綴,所以我們回傳 3。
解題思維:
就單純用一個布林陣列 H(用來記錄每個影片是否已經被上傳到伺服器了)以及一個變數 C(用來表示最長的已上傳前綴之長度)。
而每當呼叫 upload() 時,會把 H[video] 設為真(代表已上傳),此時我們可以判斷一下是否可以延長「先前」的已上傳前綴。也就是說每當 H[C] 為真時,代表我們可以再延長該前綴。因此 C 會被加一。
也因此,每當呼叫 longest() 時,只要回傳 C 之值即可。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。