LeetCode 4 尋找兩個正序陣列的中位數

2021-10-08 01:52:57 字數 1993 閱讀 1997

題目要求的時間複雜度是log(m + n),如果不對時間複雜度做要求可以使用雙指針對陣列進行遍歷即可。

我們把這個題轉換成查詢第k小整數,解題思路如下:   

首先宣告,下面的思路非常值得反覆複習。

假設我們要找第 7 小的數字。

我們比較兩個陣列的第 k/2 個數字,如果 k 是奇數,向下取整。也就是比較第 3 個數字,上邊陣列中的 4 和下邊陣列中的 3,如果哪個小,就表明該陣列的前 k/2 個數字都不是第 k 小數字,所以可以排除。也就是 1,2,3 這三個數字不可能是第 7小的數字,我們可以把它排除掉。將 1349 和 45678910兩個陣列作為新的陣列進行比較。    

更一般的情況 a[1] ,a[2] ,a[3],a[k/2] ... ,b[1],b[2],b[3],b[k/2] ... ,如果 a[k/2]橙色的部分表示已經去掉的數字。

由於我們已經排除掉了 3 個數字,就是這 3 個數字一定在最前邊,所以在兩個新陣列中,我們只需要找第 7 - 3 = 4 小的數字就可以了,也就是 k = 4。此時兩個陣列,比較第 2 個數字,3 < 5,所以我們可以把小的那個陣列中的 1 ,3 排除掉了。

我們又排除掉 2 個數字,所以現在找第 4 - 2 = 2 小的數字就可以了。此時比較兩個陣列中的第 k / 2 = 1 個數,4 == 4,怎麼辦呢?由於兩個數相等,所以我們無論去掉哪個陣列中的都行,因為去掉 1 個總會保留 1 個的,所以沒有影響。為了統一,我們就假設 4 > 4 吧,所以此時將下邊的 4 去掉       

由於又去掉 1 個數字,此時我們要找第 1 小的數字,所以只需判斷兩個陣列中第乙個數字哪個小就可以了,也就是 4。

所以第 7 小的數字是 4。

注意,我們每次都是取 k/2 的數進行比較,有時候可能會遇到陣列長度小於 k/2的時候。

此時 k / 2 等於 3,而上邊的陣列長度是 2,我們此時將箭頭指向它的末尾就可以了。這樣的話,由於 2 < 3,所以就會導致上邊的陣列 1,2 都被排除。造成下邊的情況。

由於 2 個元素被排除,所以此時 k = 5,又由於上邊的陣列已經空了,我們只需要返回下邊的陣列的第 5 個數字就可以了。

從上邊可以看到,無論是找第奇數個還是第偶數個數字,對我們的演算法並沒有影響,而且在演算法進行中,k 的值都有可能從奇數變為偶數,最終都會變為 1 或者由於乙個陣列空了,直接返回結果。

所以我們採用遞迴的思路,為了防止陣列長度小於 k/2,所以每次比較 min(k/2,len(陣列) 對應的數字,把小的那個對應的陣列的數字排除,將兩個新陣列進入遞迴,並且 k 要減去排除的數字的個數。遞迴出口就是當 k=1 或者其中乙個數字長度是 0 了。

class solution else

}int getkminnum(vector&nums1, int start1, int end1, vector&nums2, int start2, int end2, int k)else}};

leetcode4 尋找兩個正序陣列的中位數

參考題解 題解 給定兩個大小為 m 和 n 的正序 從小到大 陣列 nums1 和 nums2。請你找出這兩個正序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 你可以假設 nums1 和 nums2 不會同時為空。示例 1 nums1 1,3 nums2 2 則中位數是 2.0 示...

LeetCode 4 尋找兩個正序陣列的中位數

給定兩個大小為 m 和 n 的正序 從小到大 陣列 nums1 和 nums2。請你找出這兩個正序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 你可以假設 nums1 和 nums2 不會同時為空。示例 1 nums1 1,3 nums2 2 則中位數是2.0 示例 2 nums1...

LeetCode 4 尋找兩個正序陣列的中位數

原題目 思路 如果某乙個陣列的長度為零,直接返回另外乙個陣列的中位數,否則 用雙指標法將兩個陣列合併為乙個陣列 o n m 然後返回該陣列的中位數。class solution else if n 0 else int count 0,i 0,j 0 vectors n m while iwhile...