leetcode4 寻找两个正序数组的中位数(困难)

参考【第 k 小数解法】你懂了吗?

题目

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

在这里插入图片描述
进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决此问题吗?

思路

题目有多种解法,难点在于用O(log (m+n))的方法去解决。
方法一:暴力法
直接将两个数组归并,合成一个新数组,再按题目的意思求中位数。奇数个数就找m+n/2+1,偶数个数找 m+n/2,m+n/2+1。复杂度O(m+n)

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
          int m=nums1.length;
          int  n=nums2.length;
          int  x= (m+n)/2;
          int[] result=new int[m+n];
          double mid=0.0;
           
          int p1=0;
          int p2=0;
          int p=0;
          while(p1<m&&p2<n) 
          {
              result[p++]=nums1[p1]<nums2[p2]?nums1[p1++]:nums2[p2++];
          }
          if(p1<m)
           {
               System.arraycopy(nums1,p1,result,p,m-p1);
           }
           if(p2<n)
           {
               System.arraycopy(nums2,p2,result,p,n-p2);
           }
       
            if((m+n)%2==0)
            mid=(double) (result[x]+result[x-1])/2;
            else
            mid=result[x];
        return mid;    
    }
    
}

方法二:双指针
直接找中位数,不需要归并,利用两个指针,将两个数组遍历,到达中位数位置就停下。复杂度O(m+n)
在这里插入图片描述

方法三:找第k小数
找中位数其实可以转换成找第k小数,k就是m+n/2+1。只要掌握求第K小数就行。
具体解法:同样以1~17为例
1.求k,(1+17)/2=9
2.折半, k / 2 = 4
在这里插入图片描述

3.将折半的两组数的最大值进行比较,4和12,删掉小的那组,1234删掉。
4.删掉之后重新上述过程,还剩9-4=5 现在变成找第5小的数,5/2=2
5.比较6和10,删掉56在这里插入图片描述
6.一直重复直到不能删。
在这里插入图片描述

关于为什么比较两组数中最大的数,删掉小的那组就行的原因。
换句话说怎么证明4一定不是第k小的。
假设4是第k个数左边的,只需证明第k个数右边的位置,在1234是左边的情况下是能够填满的。
在这里插入图片描述

方法四:官方给出的划分数组
也是利用二分查找,但看不太明白。。。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值