Median of Two Sorted Arrays - LeetCode

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

You may assume nums1 and nums2 cannot be both empty.

Example 1:

nums1 = [1, 3]
nums2 = [2]

The median is 2.0
Example 2:

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5

解析:这题要求时间复杂度为log(m+n),按照传统思路绝壁不行,所以这里需要思考一下。题目所给的是two sorted arrays,那我们可以假设这两个数组都为非降序,现在让我们来解出中位数,首先中位数的值跟两数组长度之和有关,长度为奇数,取中间,为偶数,取中间两值平均值,其次由于数组是有序的,故我们求其中位数时可以转化为求第k小数问题,例如给定A=[1,3],B=[2,4],其中位数易知为2.5,怎么算呢?两数组长度之和为4,我们要求中位数须求得其第2和第3位数字是多少,当求第2位数字时,我们需要对2进行二分(以判断第2位数字究竟在哪个数组中),对2二分得1(即求两个数组中对应的第1小数),我们发现A[1-1]<B[1-1](注意:我们求某位数,但是数组下标从零开始,故减一),那么第2个数肯定不在数组A[1-1]前,我们就要舍弃数组A[1-1]前一部分变成数组A’,求第2小数也就变成了求第1小数,通过对比A’[1-1]=3,而B[1-1]=2,那么对于两数组而言第2小数肯定就为2了,同理求得第3小数为3,解得中位数为(2+3)/2=2.5.

解法:①C++

    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
      int m=nums1.size(),n=nums2.size();
      //若m+n为奇数,相当于求两次中位数再除2,结果不变,为偶数,则相当于求中间两数均值
      return (getkth(nums1,nums2,(m+n+1)/2)+getkth(nums1,nums2,(m+n+2)/2))/2.0;
    }
    double getkth(vector<int> A,vector<int> B,int k){
      if(A.size()>B.size()) return getkth(B,A,k); //为方便计算第k小数,须保证前者长度小于后者长度
      if(A.size()==0) return B[k-1]; //A数组不存在第k小数,那么必然存在于B数组
      if(B.size()==0) return A[k-1]; 
      if(k==1) return min(A[0],B[0]); //若求第1小数,则需取两数组头数较小值即可
      int la=min(k/2,(int)(A.size())),lb=k-la; //min的作用是考虑到A数组长度可能没有达到k/2,防止越界
      if(A[la-1]>B[lb-1]) return getkth(A,vector<int>(B.begin()+lb,B.end()),k-lb); //舍弃B[lb-1]及其之前的数,更新k
      else if(A[la-1]<B[lb-1]) return getkth(vector<int>(A.begin()+la,A.end()),B,k-la);
      else return A[la-1]; //若相等,则返回其中一个即可
    }

②Java

    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
      int m=nums1.length,n=nums2.length;
      return (getkth(nums1,m,0,nums2,n,0,(m+n+1)/2)+getkth(nums1,m,0,nums2,n,0,(m+n+2)/2))/2.0;
    }
    //m,n为数组A和B的长度,a,b为数组A和B的头部位置
    private double getkth(int[] A,int m,int a,int[] B,int n,int b,int k){
      if(a==m) return B[b+k-1];
      if(b==n) return A[a+k-1];
      if(m>n) return getkth(B,n,b,A,m,a,k);
      if(k==1) return Math.min(A[a],B[b]);
      int la=Math.min(A.length-a,k/2),lb=k-la;
      if(A[a+la-1]>B[b+lb-1]) return getkth(A,m,a,B,n,b+lb,k-lb);
      else if(A[a+la-1]<B[b+lb-1]) return getkth(A,m,a+la,B,n,b,k-la);
      else return A[a+la-1];
    }

③python

    def getKth(self, A, B, k):
        lenA = len(A); lenB = len(B)
        if lenA > lenB: return self.getKth(B, A, k)
        if lenA == 0: return B[k - 1]
        if k == 1: return min(A[0], B[0])
        la = min(k/2, lenA); lb = k - la
        if A[la - 1] <= B[lb - 1]:
            return self.getKth(A[la:], B, lb)
        else:
            return self.getKth(A, B[lb:], la)

    def findMedianSortedArrays(self, A, B):
        lenA = len(A); lenB = len(B)
        return (self.getKth(A, B, (lenA + lenB + 1)/2) + self.getKth(A, B, (lenA + lenB + 2)/2)) * 0.5
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值