There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).算法
兩個排序數組,找這兩個排序數組的中位數,時間複雜度爲O(log(m+n))數組
設數組A的長度爲m, 數組B的長度爲n, 兩個數組都都是遞增有序的。spa
求這兩個數組的中位數.net
首先咱們看看中位數的特色,一個大小爲n的數組,code
若是n是奇數,則中位數只有一個,數組中剛好有 (n-1)/2 個元素比中位數小。排序
若是n是偶數,則中位數有兩個(下中位數和上中位數),這裏咱們只求下中位數,對於下中位數,get
數組中剛好有(n-1)/2個元素比下中位數小。it
此題中,中位數只有一個,它前面有 c = (m+n-1)/2 個數比它小。中位數要麼出如今數組A中,io
要麼出如今數組B中,咱們先從數組A開始找。考察數組A中的一個元素A[p], 在數組A中,ast
有 p 個數比A[p]小,若是數組B中剛好有 c-p 個數比 A[p] 小, 則倆數組合並後就剛好有 c 個數比A[p]小,
因而A[p]就是要找的中位數。 以下圖所示:
若是A[p] 剛好位於 B[c-p-1] 和 B[c-p] 之間,則 A[p] 是中位數
若是A[p] 小於 B[c-p-1] ,說明A[p] 過小了,接下來從 A[p+1] ~A[m-1]開始找
若是A[p] 大於 B[c-p] ,說明A[p] 太大了,接下來從 A[0] ~A[p-1]開始找。
若是數組A沒找到,就從數組B找。
注意到數組A和數組B都是有序的,因此能夠用二分查找。
採用類二分查找算法
public class Solution { /** * 004-Median of Two Sorted Arrays(兩個排序數組的中位數) * * @param nums1 * @param nums2 * @return */ public double findMedianSortedArrays(int[] nums1, int[] nums2) { if (nums1 == null) { nums1 = new int[0]; } if (nums2 == null) { nums2 = new int[0]; } int len1 = nums1.length; int len2 = nums2.length; if (len1 < len2) { // 確保第一個數組比第二個數組長度大 return findMedianSortedArrays(nums2, nums1); } // 若是長度小的數組長度爲0,就返回前一個數組的中位數 if (len2 == 0) { return (nums1[(len1 - 1) / 2] + nums1[len1 / 2]) / 2.0; } int lo = 0; int hi = len2 * 2; int mid1; int mid2; double l1; double l2; double r1; double r2; while (lo <= hi) { mid2 = (lo + hi) / 2; mid1 = len1 + len2 - mid2; l1 = (mid1 == 0) ? Integer.MIN_VALUE : nums1[(mid1 - 1) / 2]; l2 = (mid2 == 0) ? Integer.MIN_VALUE : nums2[(mid2 - 1) / 2]; r1 = (mid1 == len1 * 2) ? Integer.MAX_VALUE : nums1[mid1 / 2]; r2 = (mid2 == len2 * 2) ? Integer.MAX_VALUE : nums2[mid2 / 2]; if (l1 > r2) { lo = mid2 + 1; } else if (l2 > r1) { hi = mid2 - 1; } else { return (Math.max(l1, l2) + Math.min(r1, r2)) / 2; } } return -1; } }