Leetcode--Median of Two Sorted Array

  这是我做的第一道hard的题,因为看到时间限制为O(log(m+n)),所以想到了要用divide and conquer。但是如何进行divide却没有很好的思路,想到了两个方案,一个是每次去掉小于第m+n/2的数,最后剩下的就是m+n/2。但是如何确定边界条件没有想好。第二个方案是每次去掉相同数量的小于m+n/2和大于m+n/2的数,转化成更小的两个数组。

  最后看了http://blog.csdn.net/zxzxy1988/article/details/8587244发现第一种思路是可行的。

  可以把问题转化成求第k个数的问题。首先假设A元素个数小于B分别为m,n。如果数组A和数组B元素个数都大于k/2,那么比较A[k/2-1]和B[k/2-1]。比较结果分三种情况:

1.A[k/2-1]<B[k/2-1]

2.A[k/2-1]==B[k/2-1]

3.A[k/2-1]>B[k/2-1]

情况一可以推出A中前k/2个数都小于合并后的第k个数,因为A[k/2-1]最多大于A中的k/2-1以及B中的k/2-1个数,所以A[k/2-1]最多是合并后的第k-2个数。因此可以舍去A中前k/2个数。此时k变成k-k/2。

情况而可以直接看出A[k/2-1]或B[k/2-1]是第k个数。

情况三和情况一一样。

因此可以形成递归,最后会遇到如下边界条件:

当A为空或,返回B[K-1]

当k=1,返回max(A[0],B[0])

此外,如果A小于k/2那么可以比较A[m-1]和B[k-m-1]后面的情况同上。


  时间复杂度:总共去掉k个数,最好情况每次去掉一半,需要时间logk。因为k=(m+n)/2所以时间复杂度log((m+n)/2)

/**
 * Created by marsares on 15/6/3.
 */
public class MedianOfTwo {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int sum=nums1.length+nums2.length;
        if(sum%2!=0)return findKthSortedArrays(nums1,nums2,(sum+1)/2,0,0);
        else return (findKthSortedArrays(nums1,nums2,sum/2,0,0)+findKthSortedArrays(nums1,nums2,sum/2+1,0,0))/2;
    }
    public double findKthSortedArrays(int[]nums1,int[]nums2,int k,int m,int n){
        if(nums1.length-m>nums2.length-n){
            return findKthSortedArrays(nums2,nums1,k,n,m);
        }
        if(nums1.length-m==0)return nums2[n+k-1];
        if(k==1){
            if(nums1[m]>nums2[n])return nums2[n];
            else return nums1[m];
        }
        int pa=min(k/2,nums1.length-m);
        if(nums1[m+pa-1]<nums2[n+pa-1])return findKthSortedArrays(nums1,nums2,k-pa,m+pa,n);
        else if(nums1[m+pa-1]==nums2[n+pa-1]&&pa==nums1.length-m)return findKthSortedArrays(nums1,nums2,k-pa,m+pa,n);
        else if(nums1[m+pa-1]==nums2[n+pa-1]&&k%2!=0&&pa==k/2)return findKthSortedArrays(nums1,nums2,k-pa,m+pa,n);
        else if(nums1[m+pa-1]==nums2[n+pa-1])return nums1[m+pa-1];
        else return findKthSortedArrays(nums1,nums2,k-pa,m,n+pa);
    }
    private int min(int a,int b){
        if(a<=b)return a;
        else return b;
    }
    public static void main(String[]args){
        int[]nums2={2};
        int[]nums1={1,3,4};
        MedianOfTwo mot=new MedianOfTwo();
        System.out.println(mot.findKthSortedArrays(nums1,nums2,3,0,0));
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值