leetcode : median of Two Sorted Arrays
runtime 39 ms, beats 93.16% of cpp submissions
O(log(m+n)) solution with explanation
tags: binary search
🔗 link
📖 description
給定兩個 sorted array ,長度分別為 m 與 n,並回傳他們 merge 完後的中位數。
要求 worst case 時間複雜度為 O(log(m+n))
🧠 solution
在第一眼看到這個題目時最直接的想法是先將兩個陣列 merge 起來,並回傳中位數即可,但這樣做的時間複雜度是 O(m+n) ,遠遠超過了題目的限制,而看到 log 系列最直接的想法要不就是 sort ,要不就是 binary search ,一開始就給了 sorted array ,所以大概就是 binary search 的應用了。
要找到 merge 完陣列的中位數,其實就是指該數的左右元素個數一樣,於是我們就可以應用 binary search 來解決問題了,只要找到前 (m+n)/2 的元素就代表找到了,並且因為 (m+n)/2 的數值固定,所以只需要在其中一個陣列中尋找切割點 cut_point ,另一個就是前面 (m+n)/2-cut_point 個元素,兩個陣列的左區間合在一起就是 merge 完的左區間了。
在更新 binary search 的區間時,就有許多地方需要注意了, cut_point 為當前陣列右區間的開頭,cut_point-1 表示當前陣列左區間的結尾,而找到正確的切割點的標準如下。
變數說明
high : binary search 的搜尋上限
low : binary search 的搜尋下限
cut1 : 表示陣列1的切割點
cut2 : 表示陣列2的切割點
l1 : 表示陣列1左區間的尾巴
l2 : 表示陣列2左區間的尾巴
r1 : 表示陣列1右區間的開頭
r2 : 表示陣列2右區間的開頭
要模擬 merge 的過程必須要滿足一個條件, case1 陣列1左區間的尾巴要比陣列2右區間的開頭還要小,也就是 l1 <= r2 , case2 以及陣列2左區間的尾巴要比陣列1右區間的開頭還要小,也就是 l2 <= r1 ,在不滿足的狀況下才更新搜尋區間,否則回傳答案。
case1 不滿足代表陣列1左區間的尾巴太大,將 high 更新。
case2 不滿足代表陣列1右區間的開頭太大,將 low 更新。
⏳ time complexity
對較小的陣列做 binary search
總時間複雜度 O(log(min(m+n)))
📝 code
1 | class Solution { |