[Leetcode题解]004 Median of Two Sorted Arrays

[Leetcode题解] 4 Median of Two Sorted Arrays

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)).

题目传送门Median of Two Sorted Arrays

思路

  抛开题目的时间复杂度要求不看,容易想到的是两种方法。第一种,将两个数组放在一起,然后排序,然后直接找到中位数,这种方法的时间复杂度是O(nlogn);另外一种方法是采用merge,直接找到第(m+n)/2个数即可,这种方法时间复杂度是O(n)。但是题目要求的是O(log(m+n))的复杂度,应该怎么办呢?
我最初的想法是,分别求出数组A, B的中位数a,b。当a < b时,中位数肯定不会出现在A的前半段,B的后半段。因此去掉这两个半段,将剩下的数组继续求中位数,然后递归的进行判断。但是后来发现这种方法不可行,会将中位数丢弃掉的。

  后来参考了网上的思路才醍醐灌顶。这道题目求中位数可以转化为求第k小的数(其中k = (m+n)/2)。
  方法是比较A[k/2-1]B[k/2-1]
  1. 若A[k/2-1] < B[k/2-1],则A[0]~A[k/2-1]肯定都是A,B两个数组合并后的数组的前k小的数。也就是说A[k/2-1]不可能大于A,B合并后的第k小的数。证明如下:假设A[k/2-1]大于A,B合并后的第k小的数,不妨设A[K/2-1]是第k+a小的数(a是正整数),那么由于A[k/2-1] < B[k/2-1],那么假设B[k/2-1]是第k+b小的数(b>a)。但是A数组中最多有k/2-1个元素小于A[k/2-1],B数组中也最多有k/2-1个元素小于A[k/2-1],那么合并后最多有k-2个元素小于A[k/2-1],这与A[k/2-1]是第k+a小的数矛盾。因此我们可以将A[0]~A[k/2-1]抛弃,问题转化为在剩下的数据中找到第k-k/2小的数。
  2. 若A[k/2-1] > B[k/2-1],思路同上
  3. 若A[k/2-1] < B[k/2-1],则找到第k小的数,返回结果。
 

解法

我的代码如下所示:

#define min(x, y) (((x)>(y))?(y):(x))

double find_the_kth(int * a, int m, int * b, int n, int k)
{
    if(m > n)
    {
        return find_the_kth(b, n, a, m, k);
    }

    if(m == 0)
        return b[k - 1];
    if(k == 1)
        return min(a[0], b[0]);

    /* devide k into two parts */
    int pa = min(k/2, m);
    int pb = k - pa;

    if(a[pa - 1] < b[pb - 1])
        return find_the_kth(a + pa, m - pa, b, n, k - pa);
    else if(a[pa - 1] > b[pb - 1])
        return find_the_kth(a, m, b + pb, n - pb, k - pb);
    else
        return a[pa - 1];
}


double findMedianSortedArrays(int * nums1, int nums1Size, int * nums2, int nums2Size) 
{
    int total = nums1Size + nums2Size;
    if(total & 0x01)
    {
        return find_the_kth(nums1, nums1Size, nums2, nums2Size, total/2 + 1);
    }
    else
    {
        return (find_the_kth(nums1, nums1Size, nums2, nums2Size, total/2)+
            find_the_kth(nums1, nums1Size, nums2, nums2Size, total/2 + 1))/2;
    }
}

参考文章

http://blog.csdn.net/yutianzuijin/article/details/11499917/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值