求两个序列的中位数代码
时间: 2024-05-10 14:02:19 浏览: 115
假设有两个长度分别为 m 和 n 的有序数组 nums1 和 nums2。为了找到两个数组的中位数,需要将两个数组合并成一个有序数组,并找到这个有序数组的中位数。
以下是一种常见的解法,时间复杂度为 O(log(m+n)):
```
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int m = nums1.size();
int n = nums2.size();
if (m > n) {
return findMedianSortedArrays(nums2, nums1); // 保证 nums1 的长度小于等于 nums2 的长度
}
int iMin = 0, iMax = m;
while (iMin <= iMax) {
int i = (iMin + iMax) / 2;
int j = (m + n + 1) / 2 - i;
if (j != 0 && i != m && nums2[j - 1] > nums1[i]) {
iMin = i + 1; // i 太小了,需要右移
} else if (i != 0 && j != n && nums1[i - 1] > nums2[j]) {
iMax = i - 1; // i 太大了,需要左移
} else { // i 刚好合适,或 i 已经移动到边界
int maxLeft = 0;
if (i == 0) { maxLeft = nums2[j - 1]; }
else if (j == 0) { maxLeft = nums1[i - 1]; }
else { maxLeft = max(nums1[i - 1], nums2[j - 1]); }
if ((m + n) % 2 == 1) { return maxLeft; } // 如果大数组的长度是奇数,中位数就是左半部分的最大值
int minRight = 0;
if (i == m) { minRight = nums2[j]; }
else if (j == n) { minRight = nums1[i]; }
else { minRight = min(nums2[j], nums1[i]); }
return (maxLeft + minRight) / 2.0; // 如果大数组的长度是偶数,取左侧最大值和右侧最小值的平均数为中位数
}
}
return 0.0;
}
};
```
这个算法的基本思想是,将数组 nums1 和 nums2 分别划分为两部分 leftPart 和 rightPart,使得 leftPart 中的元素都小于 rightPart 中的元素,然后中位数就是 leftPart 中的最大值和 rightPart 中的最小值的平均数。为了满足这个条件,需要满足以下两个条件:
1. len(leftPart) == len(rightPart) (两个数组的长度之和是偶数)
或者
2. len(leftPart) == len(rightPart) + 1 (两个数组的长度之和是奇数)
在算法中,使用 i 和 j 分别表示 nums1 和 nums2 中分割线的位置,iMax 和 iMin 分别表示二分查找的上下界。在每次迭代中,根据 nums1[i-1] 和 nums2[j-1] 的大小关系,调整 iMax 或 iMin 的值,直到找到合适的 i 和 j。
阅读全文