Leetcode 4. 寻找两个正序数组的中位数

题目

  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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值