LeetCode_4.尋找兩個正序陣列的中位數
阿新 • • 發佈:2020-12-19
給定兩個大小為 m 和 n 的正序(從小到大)陣列nums1
和nums2
。請你找出並返回這兩個正序陣列的中位數。
進階:你能設計一個時間複雜度為 O(log (m+n))
的演算法解決此問題嗎?
示例 1:
輸入:nums1 = [1,3], nums2 = [2] 輸出:2.00000 解釋:合併陣列 = [1,2,3] ,中位數 2
示例 2:
輸入:nums1 = [1,2], nums2 = [3,4] 輸出:2.50000 解釋:合併陣列 = [1,2,3,4] ,中位數 (2 + 3) / 2 = 2.5
示例 3:
輸入:nums1 = [0,0], nums2 = [0,0] 輸出:0.00000
示例 4:
輸入:nums1 = [], nums2 = [1] 輸出:1.00000
示例 5:
輸入:nums1 = [2], nums2 = [] 輸出:2.00000
提示:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106
C#程式碼
public class Solution { public double FindMedianSortedArrays(int[] nums1, int[] nums2) { /* * 中位數兩種場景:1)奇數取最中間一個數;2)偶數取最中間兩個數均值。 * 兩陣列升序排列,最左側元素最小,依次取出最左側元素中較小值,按照取出順序排列,被取出元素陣列指標右移。 * 可以採用新陣列儲存取出資料,兩陣列元素全部取出後,新陣列中間位置即可求中位數。 * 時間複雜度O(m+n),空間複雜度O(m+n)。 * 可以嘗試優化空間複雜度,若對於兩陣列長度都很大場景,會佔用大量的系統記憶體,甚至造成程式崩潰問題。 * 優化思路:基於兩陣列升序排列及中位數特點,當新陣列長度達到兩陣列長度一半時,已經可以計算出中位數了; * 無論兩陣列總長度奇偶性如何,中位數最多與兩個資料有關,使用變數記錄新陣列當前索引指向元素及前序元素即可。 * 調整後空間複雜度O(1),時間複雜度O(m+n)【量級未改變,但實際變為原來耗時的一半。】。 */ /*中位數索引(針對奇數)或中位數右側元素索引(針對偶數)。*/ int m = (nums1.Length + nums2.Length) / 2; /*使用臨時變數記錄上一次被取出元素及當前被取出元素。*/ int v1 = 0; int v2 = 0; /*定義訪問num1、num2兩陣列的索引指標*/ int m1 = 0; int m2 = 0; /*並未完成對num1、num2任一陣列的訪問場景。*/ while(m1 < nums1.Length && m2 < nums2.Length && (m1 + m2) <= m){ v1 = v2; v2 =nums1[m1] <= nums2[m2] ? nums1[m1++] :nums2[m2++]; } /*針對num1未完成訪問場景處理。*/ while(m1 < nums1.Length && (m1 + m2) <= m){ v1 = v2; v2 = nums1[m1++]; } /*針對num2未完成訪問場景處理。*/ while(m2 < nums2.Length && (m1 + m2) <= m){ v1 = v2; v2 = nums2[m2++]; } /*基於兩陣列總長度奇偶性返回結果:奇數返回v2,偶數返回v1、v2均值。*/ return (nums1.Length + nums2.Length) % 2 == 1 ? (double)v2 : (double)(v1 + v2) / 2; } }