描述
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
示例 1:
nums1 = [1, 3]
nums2 = [2]则中位数是 2.0
示例 2:
nums1 = [1, 2]
nums2 = [3, 4]则中位数是 (2 + 3)/2 = 2.5
难点:
复杂度要求是m+n,所以肯定不能用排序。
思路:
在不用排序的情况下,看了很多大佬说用二分法的思想,我这里是用一个大顶堆一个小顶堆来维护(利用的堆的严格有序),首先保证大顶堆的每个元素都小于小顶堆里面的元素,其次,保证两个堆里面的元素数量相差在1以内,最后,如果两个堆的元素数量相差为1,则多的那个堆顶为中位数,如果两个堆的数量相等,则两个堆顶元素的平均值为中位数。详见代码实现。
代码实现:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
priority_queue<int> big;
priority_queue<int, vector<int>, greater<int>> small;
double ans = 0;
int num1_len = nums1.size();
int num2_len = nums2.size();
for (int i = 0; i < num1_len; i++)
{
if (big.size() == 0 || (big.size() != 0 && nums1[i] <= big.top()))
{
big.push(nums1[i]);
} else
{
small.push(nums1[i]);
}
if (big.size() > small.size() && big.size() - small.size() >= 2)
{
small.push(big.top());
big.pop();
} else if (small.size() > big.size() && small.size() - big.size() >= 2)
{
big.push(small.top());
small.pop();
}
}
for (int i = 0; i < num2_len; i++)
{
if (big.size() == 0 || (big.size() != 0 && nums2[i] <= big.top()))
{
big.push(nums2[i]);
} else
{
small.push(nums2[i]);
}
if (big.size() > small.size() && big.size() - small.size() >= 2)
{
small.push(big.top());
big.pop();
} else if (small.size() > big.size() && small.size() - big.size() >= 2)
{
big.push(small.top());
small.pop();
}
}
if(big.size() == small.size()){
ans = (double)(big.top() + small.top()) / 2;
} else if(big.size() > small.size()){
ans = big.top();
} else {
ans = small.top();
}
return ans;
}