给定两个大小分别为 m
和 n
的正序(从小到大)数组 nums1
和 nums2
。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n))
。
示例 1:
输入:nums1 = [1,3], nums2 = [2] 输出:2.00000 解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4] 输出:2.50000 解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
提示:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106
直接暴力很好做,但是题目有时间复杂度要求,这里不展示
因为时间复杂度中有log,向二分法的方向考虑,求中位数的问题可以变成求两个有序数组中第k小数的问题,具体详解见力扣题解区
#include <iostream>
#include "string"
#include "vector"
#include "list"
#include "unordered_set"
using namespace std;
double Find(vector<int>& nums1, int star1,int end1,vector<int>& nums2,int star2,int end2,int k)
{
int temp=k/2;
//求数组1和数组2的长度
int n=end1-star1;
int m=end2-star2;
//边界情况,如果数组1中没有数,返回数组2中第k小数
if(n==0)
{
return nums2[k+star2-1];
}
//同上
else if(m==0)
{
return nums1[k-1+star1];
}
//如果k为1,取数组1和2中较小数即可
if(k==1)
{
return min(nums1[star1],nums2[star2]);
}
//如果数组1的长度小于k/2,则根据数组1的长度选取比较的数
if(n<=k/2)
{
if(nums1[n+star1-1]<nums2[n+star2-1])
{
return Find(nums1,end1,end1,nums2,star2,end2,k-n);
}
else if(nums1[n+star1-1]>=nums2[n+star2-1])
{
return Find(nums1,star1,end1,nums2,star2+n,end2,k-n);
}
}
//同上,数组2
else if(m<=k/2)
{
if(nums1[m+star1-1]<nums2[m+star2-1])
{
return Find(nums1,star1+m,end1,nums2,star2,end2,k-m);
}
else if(nums1[m+star1-1]>=nums2[m+star2-1])
{
return Find(nums1,star1,end1,nums2,end2,end2,k-m);
}
}
if(nums1[k/2+star1-1]<nums2[k/2+star2-1])
{
//cout<<"nums1:"<<nums1[k/2+star1-1]<<endl<<"nums2:"<<nums2[k/2+star2-1]<<endl;
return Find(nums1,star1+k/2,end1,nums2,star2,end2,k-k/2);
} else
{
return Find(nums1,star1,end1,nums2,star2+k/2,end2,k-k/2);
}
return 0;
}
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2)
{
int sum;
sum=nums1.size()+nums2.size();
int k=sum/2+1;
//如果数组长度之和为奇数,取最中间的数即可
if(sum%2!=0)
{
return Find(nums1,0,nums1.size(),nums2,0,nums2.size(),k);
}
//如果是偶数,取两数之和
else if(sum%2==0)
{
//return (Find(nums1,0,nums1.size(),nums2,0,nums2.size(),k-1)+ Find(nums1,0,nums1.size(),nums2,0,nums2.size(),k))/2;
double k1= Find(nums1,0,nums1.size(),nums2,0,nums2.size(),k-1);
double k2=Find(nums1,0,nums1.size(),nums2,0,nums2.size(),k);
return (k1+k2)/2;
}
return 0;
}
//自主测试
int main() {
vector<int> num1;
vector<int> num2;
int sum;
cin >> sum;
while (sum != -1) {
num1.push_back(sum);
cin >> sum;
}
cin >> sum;
while (sum != -1) {
num2.push_back(sum);
cin >> sum;
}
double count = findMedianSortedArrays(num1, num2);
cout << count;
}