你有 k 個公升序排列的整數列表。找到乙個最小區間,使得 k 個列表中的每個列表至少有乙個數包含在其中。
我們定義如果 b-a < d-c 或者在 b-a == d-c 時 a < c,則區間 [a,b] 比 [c,d] 小。
例如:輸入:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]
輸出:[20,24]
解釋:列表 1:[4, 10, 15, 24, 26],24 在區間 [20,24] 中。
列表 2:[0, 9, 12, 20],20 在區間 [20,24] 中。
列表 3:[5, 18, 22, 30],22 在區間 [20,24] 中
翻譯一下題目 分析
那上述例子來進行分析
4 10 15 24 26①:先建立乙個最小堆,把列表的第乙個數字都入堆,在入堆的過程中,記錄min、max值,很明顯 min 和 max 組合起來的區間,就是答案了。0 9 12 20
5 18 22 30
②:那麼現在問題轉化成:如何去更新min、max值讓去縮小區間?很顯然,要不使min變大,要不max變小。而從題目裡我們可以知道,每個列表都是單調遞增的,所以,max是無法變小的(或者說,變小都是已經考慮過的情況)。
③:所以問題轉化成,如何讓min變大?首先,min值是處於某個列表裡的,那麼我們馬上就可以反應到:我們可以使min值所在的下標往後移動一位。可能有同學會有疑問,這樣子沒有考慮到其他列表。解決這個問題,我們可以在min往後移動一位之前,把min出堆,移動一位之後,重新把移動的這一位入堆,然後在取到堆頂,重新設定min,這樣子min值就都考慮到了每個列表。
④:什麼時候可以判斷 min、max是最小區間?min所在列表,已經走到底部了,就是最小區間了。因為當min為目前堆裡最小並且是列表最大時,min值已經無法再次變大了。
附上**
public
int[
]smallestrange
(list
> nums)})
;int start = integer.max_value;
int end = integer.min_value;
int max = integer.min_value;
for(
int i =
0; i < nums.
size()
; i++
) integer value = list.
get(0)
; start = math.
min(start,value)
; end = math.
max(end,value)
; priorityqueue.
add(
newmodel
(value,i,0)
);max = math.
max(max,value);}
while
(true
)int min = priorityqueue.
peek()
.data;
if(max - min < end - start)
else
if(max - min == end - start && min < start)
}else
}return
newint
;}public
static
class
model
}
leetcode632 最小區間 堆
你有 k 個公升序排列的整數陣列。找到乙個最小區間,使得 k 個列表中的每個列表至少有乙個數包含在其中。我們定義如果 b a d c 或者在 b a d c 時 a c,則區間 a,b 比 c,d 小。示例 1 輸入 4,10,15,24,26 0,9,12,20 5,18,22,30 輸出 20 ...
LeetCode 632 最小區間(雙指標)
題意 你有 k 個 非遞減排列 的整數列表。找到乙個 最小 區間,使得 k 個列表中的每個列表至少有乙個數包含在其中。我們定義如果 b a d c 或者在 b a d c 時 a c,則區間 a,b 比 c,d 小。示例 1 輸入 nums 4,10,15,24,26 0,9,12,20 5,18,...
尺取法(單調性 找區間個數或最小區間)
尺取法只能具有單調性的資料 反覆地推進區間的開頭和末尾,來找滿足條件的最小區間 一般要求個數或者是最小的 右端到臨界狀態後,判斷是否滿足條件,更新結果 左端右移 num具有單調性,可用尺取法 include includeusing namespace std include include inc...