题目
Leetcode 4. 寻找两个正序数组的中位数
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
解题思路
方法1:将数组合并为一个大的数组,直接取中位数即可。
优化方法采用优先队列 priority_queue,将数组nums1插入队列中,然后依次插入nums2的数据,并弹出优先队列的堆顶元素,直到弹出个数到达中位数的个数,即可。
方法二:采用二分查找
由两个数组的大小直接可以计算出中位数的在的位置K,
K = (nums1.size()+nums2.size())/2 +1;
采用二分法 直接对比 nums1[ k/2 -1]和 nums2[ k/2 -1]的大小
如果 nums1[ k/2 -1]< nums2[ k/2 -1],那么两个数组中最多有k-2个数比 nums1[ k/2 -1]小,因此中位数必定在nums1[ k/2 -1]之后,因此可以我们可以排除数组nums1下标为k/2之前的数。
从而大大减少了时间复杂度。
解题代码
下面展示一些 内联代码片
。
// C++ 方法二 (二分查找)
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size();
int m = nums2.size();
//不加1,就表示合并后数组的中位数下标,加1就表示合并后数组第几个为中位数
int len = (n+m)/2+1;
if((n+m)%2 == 1)
{
return findmidbit(nums1,0,nums2,0,len);
}else{
//int整数除以int整数一定得到的是int整数
//因此可在前面强制转换成 double.或者将2写成2.0
return (findmidbit(nums1,0,nums2,0,len)+ findmidbit(nums1,0,nums2,0,len-1))/2.0;
}
}
//引入二分后 删除数组的 起始下标 i j
//k表示第几位数 为中位数
int findmidbit(vector<int>&A,int i,vector<int>&B,int j,int k)
{
//当数组在二分查找过程中,全部杯排除后,直返回B数组的第k个数
//列入 数组[1,2]和[3,4],在查找第三个数时,A数组会被舍弃 i为2
if(i>=A.size())
{
return B[j+k-1]; //K表示要查找第几个数,与下标要减1
}
//B数组同理
if(j>=B.size())
{
return A[i+k-1];
}
//边界条件怎么考虑得到的
if(k == 1)
{
return min(A[i],B[j]);
}
int A_fen = i+k/2-1<A.size()?A[i+k/2-1]:INT_MAX;
int B_fen = j+k/2-1<B.size()?B[j+k/2-1]:INT_MAX;
//当两者相等的时候,是否作为一种单列的情况
if(A_fen<B_fen)
{
//i+k/2-1 是否要加1
return findmidbit(A,i+k/2,B,j,k-k/2);
}else{
//j+k/2-1 是否要加1
return findmidbit(A,i,B,j+k/2,k-k/2);
}
}
};
// // C++ 方法一 (优先队列)
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size();
int m = nums2.size();
int midbit = (n+m)/2;
int num = 0;
double ans1 = 0;
priority_queue<int,vector<int>,greater<int>> que;
for(int i = 0;i<n;i++)
{
que.push(nums1[i]);
}
while(num<=midbit)
{
if(num<m)
{
que.push(nums2[num]);
}
if((n+m)%2 ==0)
{
if(num >=midbit-1 && num <=midbit)
{
ans1=ans1+que.top();
if(num == midbit)
{
ans1 = ans1/2;
return ans1;
}
}
}
else{
if(num == midbit)
{
return que.top();
}
}
if(!que.empty())
{
que.pop();
}
num++;
}
return ans1;
}
};