兩個已排序數組 A(m)、B(n),求合併後的中位數。等價於找第 k = (m+n)/2 小元素(奇數情況)或前兩者平均(偶數情況)。要求 O(log(m+n)) 時間。
比較 A[k/2-1] 與 B[k/2-1](兩數組各自的第 k/2 小元素):
A[k/2-1] < B[k/2-1] → A 前 k/2 個元素不可能是第 k 小,遞歸在 A[k/2...] 和 B 中找第 k - k/2 小> → 同理捨棄 B 前 k/2 個= → 直接返回該值(理想情況)pa,pb = k - padouble findKth(int A[], int m, int B[], int n, int k) {
if (m > n) return findKth(B, n, A, m, k); // 保證 m ≤ n
if (m == 0) return B[k-1];
if (k == 1) return min(A[0], B[0]);
int pa = min(k/2, m), pb = k - pa;
if (A[pa-1] < B[pb-1])
return findKth(A+pa, m-pa, B, n, k-pa);
else if (A[pa-1] > B[pb-1])
return findKth(A, m, B+pb, n-pb, k-pb);
else return A[pa-1];
}
class Solution {
public:
double findMedianSortedArrays(int A[], int m, int B[], int n) {
int total = m + n;
if (total & 1) return findKth(A, m, B, n, total/2 + 1);
return (findKth(A, m, B, n, total/2) + findKth(A, m, B, n, total/2 + 1)) / 2.0;
}
};
詳細推導可參考:CSDN 經典講解
每次遞歸 k 減少約一半,遞歸深度 O(log k) = O(log(m+n))。每層 O(1) 操作,總體 O(log(m+n)),完美滿足要求。