LeetCode(4) 尋找兩個有序陣列的中位數

2021-09-26 01:09:38 字數 2507 閱讀 1475

給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 o(log(m + n))。你可以假設 nums1 和 nums2 不會同時為空。

簡單粗暴,先將兩個陣列合併,兩個有序陣列的合併也是歸併排序中的一部分。然後根據奇數,還是偶數,返回中位數。

public double findmediansortedarrays(int nums1, int nums2)  else 

}if (n == 0) else

}int count = 0;

int i = 0, j = 0;

while (count != (m + n))

break;

}if (j == n)

break;

}if (nums1[i] < nums2[j]) else

}if (count % 2 == 0) else

}

時間複雜度:遍歷全部陣列 (m+n)

空間複雜度:開闢了乙個陣列,儲存合併後的兩個陣列 o(m+n)

其實,我們不需要將兩個陣列真的合併,我們只需要找到中位數在**就可以了。

開始的思路是寫乙個迴圈,然後裡邊判斷是否到了中位數的位置,到了就返回結果,但這裡對偶數和奇數的分類會很麻煩。當其中乙個陣列遍歷完後,出了 for 迴圈對邊界的判斷也會分幾種情況。總體來說,雖然複雜度不影響,但**會看起來很亂。

首先是怎麼將奇數和偶數的情況合併一下。

用 len 表示合併後陣列的長度,如果是奇數,我們需要知道第 (len+1)/2 個數就可以了,如果遍歷的話需要遍歷 int(len/2 ) + 1 次。如果是偶數,我們需要知道第 len/2和 len/2+1 個數,也是需要遍歷 len/2+1 次。所以遍歷的話,奇數和偶數都是 len/2+1 次。

返回中位數的話,奇數需要最後一次遍歷的結果就可以了,偶數需要最後一次和上一次遍歷的結果。所以我們用兩個變數 left 和 right,right 儲存當前迴圈的結果,在每次迴圈前將 right 的值賦給 left。這樣在最後一次迴圈的時候,left 將得到 right 的值,也就是上一次迴圈的結果,接下來 right 更新為最後一次的結果。

迴圈中該怎麼寫,什麼時候 a 陣列後移,什麼時候 b 陣列後移。用 astart 和 bstart 分別表示當前指向 a 陣列和 b 陣列的位置。如果 astart 還沒有到最後並且此時 a 位置的數字小於 b 位置的陣列,那麼就可以後移了。也就是astart<m&&a[astart]< b[bstart]。

但如果 b 陣列此刻已經沒有數字了,繼續取數字 b[ bstart ],則會越界,所以判斷下 bstart 是否大於陣列長度了,這樣 || 後邊的就不會執行了,也就不會導致錯誤了,所以增加為 astart<m&&(bstart)>= n||a[astart]= n || a[astart] < b[bstart])) else

}if ((len & 1) == 0)

return (left + right) / 2.0;

else

return right;

}時間複雜度:遍歷 len/2+1 次,len=m+n,所以時間複雜度依舊是 o(m+n)。

空間複雜度:我們申請了常數個變數,也就是 m,n,len,left,right,astart,bstart 以及 i。

總共 8 個變數,所以空間複雜度是 o(1)。

上邊的兩種思路,時間複雜度都達不到題目的要求 o(log(m+n)。看到 log,很明顯,我們只有用到二分的方法才能達到。我們不妨用另一種思路,題目是求中位數,其實就是求第 k 小數的一種特殊情況,而求第 k 小數有一種演算法。

解法二中,我們一次遍歷就相當於去掉不可能是中位數的乙個值,也就是乙個乙個排除。由於數列是有序的,其實我們完全可以一半兒一半兒的排除。假設我們要找第 k 小數,我們可以每次迴圈排除掉 k/2 個數。看下邊乙個例子。

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

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

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

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

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

LeetCode4 尋找兩個有序陣列的中位數

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