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

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

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二分查找

class Solution {
    int[] nums1;
    int[] nums2;
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        this.nums1=nums1;
        this.nums2=nums2;
         int m=nums1.length;
         int n=nums2.length;
         return (getMid(0,0,(m+n+1)/2)+getMid(0,0,(m+n+2)/2))/2.0;
    }
   
   int getMid(int i,int j,int flg)
   {
       if(i>=nums1.length)return nums2[j+flg-1];
       if(j>=nums2.length)return nums1[i+flg-1];
       if(flg==1)return Math.min(nums1[i],nums2[j]);
       if(i+flg/2>nums1.length)
       {
          return getMid(i,j+flg/2,flg-flg/2);

       }else if(j+flg/2>nums2.length)
       {
            return getMid(i+flg/2,j,flg-flg/2);
       }
       else {
           if(nums2[j+flg/2-1]<=nums1[i+flg/2-1])
           {
               return getMid(i,j+flg/2,flg-flg/2);
           }
           else
           {
                return getMid(i+flg/2,j,flg-flg/2);
           }
       }

       
   }


}

暴力查找


class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m=nums1.length;
        int n=nums2.length;
        int i=0;
        int j=0;
        int a=0;
        int b=0;
        int k=0;//用于记录已经遍历到第几个数
        if(m==0)
         return (nums2[((m+n+1))/2-1]+nums2[(m+n+2)/2-1] )/2.0;
        if(n==0)
        return (nums1[(m+n+1)/2-1]+nums1[(m+n+2)/2-1] )/2.0;
       while(k!=((m+n+2)/2))
       {
           int min=0;
           if(nums1[i]<=nums2[j])
            { min=nums1[i];
               if(i==m-1)
                nums1[i]=Integer.MAX_VALUE;//代表第一个数组已经遍历玩,并且中位数不在这
             else i++;
           }
           else {min=nums2[j];
            if(j==n-1)
             nums2[j]=Integer.MAX_VALUE;//代表第一个数组已经遍历玩,并且中位数不在这
          else j++;  }
           k++;
           if(k==((m+n+1)/2))
           a=min;
           if(k==((m+n+2)/2))
           b=min;
       }
       return (a+b)/2.0;
        
   }
}
  • 二分是用看别人思路写的,暴力是自己写的
寻找两个正序数组中位数可以使用归并的方式,合并两个有序数组,得到一个大的有序数组。然后找到大的有序数组的中间位置的元素,即为中位数。另一种方法是使用双指针的方式,维护两个指针,初始时分别指向两个数组的下标0的位置。每次将指向较小值的指针后移一位(如果一个指针已经到达数组末尾,则只需要移动另一个数组的指针),直到到达中位数的位置。这样可以在O(log(m+n))的时间复杂度内找到中位数。 具体步骤如下: 1. 初始化指针p1和p2分别指向两个数组的起始位置0。 2. 判断两个指针所指的元素大小,较小的元素所在的指针后移一位,直到其中一个指针到达数组末尾。 3. 若两个数组的长度之和为奇数,那么中位数即为当前指针指向的元素; 若两个数组的长度之和为偶数,那么中位数为当前指针指向的元素与其下一个元素的平均值。 4. 返回中位数作为结果。 需要注意的是,为了保证时间复杂度为O(log(m+n)),在每次移动指针时,应该移动的步数应该是当前指针所在数组长度的一半,即k/2,其中k为两个数组的长度之和。 以下是一个示例代码,用于说明上述方法的实现: ``` int findMedianSortedArrays(int[] nums1, int[] nums2) { int m = nums1.length; int n = nums2.length; int total = m + n; int middle = total / 2; int p1 = 0, p2 = 0; int prev = 0, curr = 0; for (int i = 0; i <= middle; i++) { prev = curr; if (p1 < m && (p2 >= n || nums1[p1 < nums2[p2])) { curr = nums1[p1++]; } else { curr = nums2[p2++]; } } if (total % 2 == 0) { return (prev + curr) / 2; } else { return curr; } } ``` 该方法可以在O(log(m+n))的时间复杂度内找到两个正序数组中位数。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [算法:寻找两个正序数组中位数。](https://blog.csdn.net/en_joker/article/details/107179641)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [寻找两个正序数组中位数](https://blog.csdn.net/wulila/article/details/124483500)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值