632. Smallest Range Covering Elements from K Lists
題目網址:https://leetcode.cn/problems/smallest-range-covering-elements-from-k-lists/
題意:給一包含
k
個非遞減排列整數 array 的 listnums
。找到一最小區間, 使得每個 array 中皆至少有一個整數包含在該區間中。定義區間
[a, b]
<[c, d]
, 滿足下列其中一個條件便成立:
b-a < d-c
b-a == d-c
且a < c
Solution 1:
想法:利用 Sliding Window, 類似 76. Minimum Window Substring
- 首先, 取出每個 array 中的最小值, 並加入到
set
中- 取出
set
中最大、最小的值, 並計算出newRange
- 若
newRange < range
, 則更新 range 和最小區間- 移除
set
中的最小元素, 並將 insert 其所對應的 array 之下一個元素
若該元素為不存在, 則直接返回e.g.
nums = [[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]
, 其中 i、j、k 分別代表idx = 0 ~ 2
的 array 當前set
中的元素 idx
- 一開始
i、j、k
皆為0
,set = {0,4,5}
。此時 set 中 [最小值, 最大值] 的區間[0, 5]
可包含每個 array 中的一個整數- 移除
set
中的最小元素0
, 並將其對應到的 array 之ptr + 1
, 也就是j + 1
。並將 9 加到 set 中。此時set = {4, 5, 9}
- 依此類推, 可參考下圖
為何是移動最小元素的 ptr?
因為如果當前
set
中的 max 不變, 而最小值變大 ➔ 最小區間的範圍會縮小e.g. 上圖中綠框的部分, 在兩次更新中 max 皆為 24, 但 min 從 18 變成 20
➔ 使得最小區間由 5 變成 4
class Solution { |
- time:$O(nk \cdot log(k))$
- 假設每個 array 的平均長度為
n
, 且總共k
個 array - $O(nk)$:總共 $nk$ 個元素
- $O(log(k))$:每次
set
新增元素,set
調整成 ordered 的所需時間為 $O(log(k))$, 因為set.insert()
是用 red-black tree 所實現的。調整成 ordered 才能在 $O(1)$ time 取得 min、max
- 假設每個 array 的平均長度為
- space:$O(k)$ ➔
set
中的元素個數不超過k
Solution 2:
想法:利用 Heap, 道理同 Solution 1
class Solution { |
- time:$O(nk \cdot log(k))$
- 假設每個 array 的平均長度為
n
, 且總共k
個 array - $O(nk)$:總共 $nk$ 個元素
- $O(log(k))$:heap 每 insert /delete 一個元素所需的時間
- 假設每個 array 的平均長度為
- space:$O(k)$ ➔ heap 中的元素個數不超過
k
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Zako's Blog!
評論