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)).
You may assume nums1 and nums2 cannot be both empty.
Example 1:
nums1 = [1, 3] nums2 = [2] The median is 2.0Example 2:
nums1 = [1, 2] nums2 = [3, 4] The median is (2 + 3)/2 = 2.5
两个排序数组的中位数,暴力求解即直接合并排序再取相应位置即可,或者得到相应位置后,两个数组一个一个遍历直到取得。
题目要求O(log (m+n)),log时间复杂度想到用二分方法来做。
首先设两个数组分别长度为x,y,则中位数为第k个或k和k+1个的平均。
因此,目标是从nums1中取m1个,从nums2中取k-m1个。即用两个分区指针来分别对两个数组分区。
分区正确的条件是 nums1[partitionX-1] <= nums2[partitionY] && nums2[partitionY-1] <= nums1[partitionX]
若分区后,左边的均小于右边的,则分区正确,再从中取得中位数即可。
若分区不正确,如x的左边的最后一个大于了y的右边的第一个,则需要将x的分区左移,相应的y的分区会右移。反之则反移。
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
const int x = nums1.size();
const int y = nums2.size();
// 确保x长度小于y
if (x > y)
return findMedianSortedArrays(nums2, nums1);
const int k = (x + y + 1) / 2; // 总的数组的中位数的位置,即左边共k个,第k个为中位数
int l = 0;
int r = x;
while (l <= r) {
int partitionX = l + (r - l) / 2;
int partitionY = k - partitionX;
// 若partitionX == 0,说明X分区后左边没有元素了,用最小值;
// 若partitionX == n,说明X分区后右边没有元素了,用最大值。确保后续的max和min的计算正确
int maxLeftX = (partitionX == 0) ? INT_MIN : nums1[partitionX - 1];
int minRightX = (partitionX == x) ? INT_MAX : nums1[partitionX];
int maxLeftY = (partitionY == 0) ? INT_MIN : nums2[partitionY - 1];
int minRightY = (partitionY == y) ? INT_MAX : nums2[partitionY];
// 满足条件时
if (maxLeftX <= minRightY && maxLeftY <= minRightX) {
if ((x + y) % 2 == 0) // 偶数时
return (max(maxLeftX, maxLeftY) + min(minRightX, minRightY)) * 0.5;
else
return max(maxLeftX, maxLeftY);
}
// 不满足,进行调整
else if (maxLeftX > minRightY) // X的left部分取多了,更改x的分区
r = partitionX - 1;
else // X的left取少了
l = partitionX + 1;
}
}
讲解视频:https://www.youtube.com/watch?v=LPFhl65R7ww&frags=pl%2Cwn