[LeetCode] 4. Median of Two Sorted Arrays 兩個有序數組的中位數
阿新 • • 發佈:2018-03-02
數據 pub art cti AI nts highlight sta binary
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)),看到這個時間復雜度,自然想到用二分搜索Binary Search。
對於一個長度為n的已排序數列a,若n為奇數,中位數為a[n / 2 + 1], 若n為偶數,則中位數(a[n / 2] + a[n / 2 + 1]) / 2; 如果我們可以在兩個數列中求出第K小的元素,便可以解決該問題; 不妨設數列A元素個數為n,數列B元素個數為m,各自升序排序,求第k小元素; 取A[k / 2] B[k / 2] 比較; 如果 A[k / 2] > B[k / 2] 那麽,所求的元素必然不在B的前k / 2個元素中(證明反證法); 反之,必然不在A的前k / 2個元素中,於是我們可以將A或B數列的前k / 2元素刪去,求剩下兩個數列的; k - k / 2小元素,於是得到了數據規模變小的同類問題,遞歸解決; 如果 k / 2 大於某數列個數,所求元素必然不在另一數列的前k / 2個元素中,同上操作就好。
參考:愛做飯的小瑩子
Java:public class Solution { public double findMedianSortedArrays(int A[], int B[]) { int len = A.length + B.length; if (len % 2 == 1) { return findKth(A, 0, B, 0, len / 2 + 1); } return ( findKth(A, 0, B, 0, len / 2) + findKth(A, 0, B, 0, len / 2 + 1) ) / 2.0; } public static int findKth(int[] A, int A_start, int[] B, int B_start, int k){ if (A_start >= A.length) { return B[B_start + k - 1]; } if (B_start >= B.length) { return A[A_start + k - 1]; } if (k == 1) { return Math.min(A[A_start], B[B_start]); } int A_key = A_start + k / 2 - 1 < A.length ? A[A_start + k / 2 - 1] : Integer.MAX_VALUE; int B_key = B_start + k / 2 - 1 < B.length ? B[B_start + k / 2 - 1] : Integer.MAX_VALUE; if (A_key < B_key) { return findKth(A, A_start + k / 2, B, B_start, k - k / 2); } else { return findKth(A, A_start, B, B_start + k / 2, k - k / 2); } } }
Python:
class Solution(object): def findMedianSortedArrays(self, nums1, nums2): """ :type nums1: List[int] :type nums2: List[int] :rtype: float """ len1, len2 = len(nums1), len(nums2) if (len1 + len2) % 2 == 1: return self.getKth(nums1, nums2, (len1 + len2)/2 + 1) else: return (self.getKth(nums1, nums2, (len1 + len2)/2) + self.getKth(nums1, nums2, (len1 + len2)/2 + 1)) * 0.5 def getKth(self, A, B, k): m, n = len(A), len(B) if m > n: return self.getKth(B, A, k) left, right = 0, m while left < right: mid = left + (right - left) / 2 if 0 <= k - 1 - mid < n and A[mid] >= B[k - 1 - mid]: right = mid else: left = mid + 1 Ai_minus_1 = A[left - 1] if left - 1 >= 0 else float("-inf") Bj = B[k - 1 - left] if k - 1 - left >= 0 else float("-inf") return max(Ai_minus_1, Bj)
C++:
class Solution { public: double findKth(vector<int>& A, vector<int>& B, int A_st, int B_st, int k) { // 邊界情況,任一數列為空 if (A_st >= A.size()) { return B[B_st + k - 1]; } if (B_st >= B.size()) { return A[A_st + k - 1]; } // k等於1時表示取最小值,直接返回min if (k == 1) return min(A[A_st], B[B_st]); int A_key = A_st + k / 2 - 1 >= A.size() ? INT_MAX : A[A_st + k / 2 - 1]; int B_key = B_st + k / 2 - 1 >= B.size() ? INT_MAX : B[B_st + k / 2 - 1]; if (A_key < B_key){ return findKth(A, B, A_st + k / 2, B_st, k - k / 2); } else { return findKth(A, B, A_st, B_st + k / 2, k - k / 2); } } double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int sum = nums1.size() + nums2.size(); double ret; if (sum & 1) { ret = findKth(nums1, nums2, 0, 0, sum / 2 + 1); } else { ret = ((findKth(nums1, nums2, 0, 0, sum / 2)) + findKth(nums1, nums2, 0, 0, sum / 2 + 1)) / 2.0; } return ret; } };
[LeetCode] 4. Median of Two Sorted Arrays 兩個有序數組的中位數