题目
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)).
Example 1:
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
Example 2:
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
代码原型
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
};
思路
- 中位数是有序列表中最中间的那个数,如果列表数有偶数个,则是中间两个数的平均。
- 这道题可以在O(m + n)时间内通过遍历解出来,但题目要求用O(log(m+n))的时间复杂度,所以不得不考虑用折半查找的方法。
对于两个已排序的数组找到它们的中位数,就是要找到A数组和B数组的分割线,使得
A[i-1] < B[j]
,B[j-1] < A[i]
,而A[i - 1]本来就小于A[i],B[j-1]本来就B[j]。这样,分割线左边的数从A[0]到A[i-1]和B[0]到B[j-1]都小于右边,于是就找到了中位数。A[0] ... A[i - 1] | A[i] ... A[n - 1] B[0] ... B[j - 1] | B[j] ... B[m - 1]
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
if (nums1.size() > nums2.size()) {
nums1.swap(nums2);
}
int size1{nums1.size()}, size2{nums2.size()};
int sizeall = size1 + size2;
int mid = (sizeall - 1)/2;
int l{0}, r{size1 - 1};
while (l <= r){
//确定l和r,使得nums1[r] < nums2[mid - r], nums1[l] > num2[mid - l]
int m1 = (r + l)>>1, m2 = mid - m1;
if (nums1[m1] < nums2[m2]) {
l = m1 + 1;
}
else {
r = m1 - 1;
}
}
int a = max(r >= 0 ? nums1[r] : 0, mid - l >= 0 ? nums2[mid - l] : 0);
//计算左边数的最大值作为中值。
if (sizeall&1) //如果整个数组的大小为奇数,则a就是中值
return a;
else { //否则,还要计算右边的最小值b,与a相加除以2得中值
int b = min(l < size1 ? nums1[l] : INT_MAX, mid - r < size2 ? nums2[mid - r] : INT_MAX);
return (a + b)/2.0;
}
}
};
运行时间 35 ms