int m = nums1.size(), n = nums2.size();
将求two arrays的中位数转化为找第(m+n+1)/2个数和第(m+n+2)/2个数,中位数为这两个数的平均值。
解法一 Olog(m+n)
如何寻找two arrays的第K个值?
每次process k/2个数,如果nums1中的第k/2个数<nums2中的第k/2个数,那么第k个数必定在nums1的第k/2个数后和nums2中;反之亦然。
Base Cases
k永远大于0,所以k=1的时候就是base case:if(k==1) return min(nums1[i],nums2[j]);
其中一条array已经遍历完:if(i==n) return nums2[j+k-1];
if(j==m) return nums1[i+k-1];
易错点:不是每次都是process k/2个数,因为有array不够长了,所以我们用 int kk = min(min(k/2, n), m);
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size()+nums2.size();
if(n==0) return 0;
return (findK(nums1, nums2, 0, 0, (n+1)/2)+findK(nums1, nums2, 0, 0, (n+2)/2))*0.5;
}
int findK(vector<int>& nums1, vector<int>& nums2, int i, int j, int k){
int n = nums1.size();
int m = nums2.size();
if(i==n) return nums2[j+k-1];
if(j==m) return nums1[i+k-1];
if(k==1) return min(nums1[i],nums2[j]);
int kk = min(min(k/2, n), m);
if(nums1[i+kk-1]<nums2[j+kk-1]) return findK(nums1, nums2, i+kk, j, k-kk);
else return findK(nums1, nums2, i, j+kk, k-kk);
}
};
解法二
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int m = nums1.size(), n = nums2.size();
if (m < n) return findMedianSortedArrays(nums2, nums1);
if (n == 0) return ((double)nums1[(m - 1) / 2] + (double)nums1[m / 2]) / 2.0;
int left = 0, right = n * 2;
while (left <= right) {
int mid2 = (left + right) / 2;
int mid1 = m + n - mid2;
double L1 = mid1 == 0 ? INT_MIN : nums1[(mid1 - 1) / 2];
double L2 = mid2 == 0 ? INT_MIN : nums2[(mid2 - 1) / 2];
double R1 = mid1 == m * 2 ? INT_MAX : nums1[mid1 / 2];
double R2 = mid2 == n * 2 ? INT_MAX : nums2[mid2 / 2];
if (L1 > R2) left = mid2 + 1;
else if (L2 > R1) right = mid2 - 1;
else return (max(L1, L2) + min(R1, R2)) / 2;
}
return -1;
}
};
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
m, n = len(nums1), len(nums2)
mid1 = (m+n+1)//2
mid2 = (m+n+2)//2
return (self.getKth(nums1, nums2, mid1)+self.getKth(nums1, nums2, mid2))/2
# k one-indexed
def getKth(self, a, b, k):
if not a:
return b[k-1]
if not b:
return a[k-1]
ai, bi = (len(a)+1)//2, (len(b)+1)//2
ae, be = a[ai-1], b[bi-1]
if ai+bi<=k:
if ae<be:
return self.getKth(a[ai:], b, k-ai)
else:
return self.getKth(a, b[bi:], k-bi)
else:
if ae<be:
return self.getKth(a, b[:bi-1], k)
else:
return self.getKth(a[:ai-1], b, k)
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
m, n = len(nums1), len(nums2)
if m>n: return self.findMedianSortedArrays(nums2, nums1)
l, r = 0, m
while l<=r:
partition1 = l + (r-l)//2
partition2 = (m+n+1)//2-partition1
L1 = nums1[partition1-1] if partition1 != 0 else float('-inf')
L2 = nums2[partition2-1] if partition2 != 0 else float('-inf')
R1 = nums1[partition1] if partition1 != m else float('inf')
R2 = nums2[partition2] if partition2 != n else float('inf')
if L1<=R2 and L2<=R1:
if (m+n)%2==0:
return (max(L1, L2)+min(R1, R2))/2
else:
return max(L1, L2)
elif L1>R2:
r = partition1-1
else:
l = partition1+1