寻找正序中位数

寻找正序中位数

题目描述:

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。

请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

难点

  • 控制时间复杂度为O(log(m+n))

主体思路

  • 复杂的带log应该考虑设计二分查找
  • 同化奇偶情况为:查找 (m+n)/2 的数和查找 (m+n)/2+1 的数
  • 广义考虑查找第K个数:
    • 假设两个有序数组分别是 A 和 B。要找到第 k 个元素,我们可以比较 A[k/2-1]和 B[k/2−1],由于 A[k/2−1] 和 B[k/2−1] 的前面分别有 k/2-1 个元素,对于 A[k/2−1] 和 B[k/2−1] 中的较小值,最多只会有 k/2−2 个元素比它小,那么它就不能是第 k 小的数了。
    • 因此可以归纳出三种情况:
      1. A[k/2-1] < B[k/2-1],则从截取之后的A子列开始
      2. A[k/2-1] > B[k/2-1],同上
      3. A[k/2-1] = B[k/2-1],可归到第一类
    • 同时将k减去适当的值
  • 应当考虑的是:
    • k/2-1越界的时候,应该使用最后一个元素;减少k的时候也应该相应的减少。

代码

int getKInArray(int* nums1, int nums1Size, int* nums2, int nums2Size, int k){
    int i=0, j=0;
    while(1){
        if(i+1>nums1Size) return nums2[j+k-1];。//貌似有bug
        else if(j+1>nums2Size) return nums1[i+k-1];
        else if(k==1) return ((nums1[i]>nums2[j])?nums2[j]:nums1[i]);
        else{
            int ni=i+k/2-1>=nums1Size?nums1Size-1:i+k/2-1;
            int nj=j+k/2-1>=nums2Size?nums2Size-1:j+k/2-1;
            if(nums1[ni]<=nums2[nj]){
                k-=ni+1-i;
                i=ni+1;
          }
          else{
              k-=nj+1-j;
              j=nj+1;
          }
        }
    }
}
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
    int k=(nums1Size+nums2Size+1)/2;
    double n1=getKInArray(nums1, nums1Size, nums2, nums2Size, k);
    k=(nums1Size+nums2Size+2)/2;
    double n2=getKInArray(nums1, nums1Size, nums2, nums2Size, k);
    return (n1+n2)/2.0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值