两排序数组的中位数(LintCode)

(lintcode)原题目:http://www.lintcode.com/zh-cn/problem/median-of-two-sorted-arrays/
(leetcode)原题目:https://leetcode.com/problems/median-of-two-sorted-arrays/description/

思路分析:这个题目常规思路很简单,合并两数组再找中位数即可,但是这样最快也是O(nlgn),但题目要求是O(lg(m+n)),所以只能用二分查找类似的方式——主要思路就是取两数组当前长度,找到当前的中位数进行比较,哪个小,就砍去对应数组的左边一半,剩下的和另外一个数组继续进行相同的操作。其实原理上,应该砍去小的数组左边的一半,大的数组右边的一半;但是砍去右边的一半,剩下的部分最后一个元素不好确定,所以一般都是只砍左边的一半。其实同时砍去大的数组右边的一半也是可以的,在函数多传入两个参数,记录当前数组最后一个元素或是用指针。以下两个链接,是我个人觉得对这个算法讲解较透彻的链接:
讲解链接:http://blog.csdn.net/ojshilu/article/details/15027309
https://discuss.leetcode.com/topic/16797/very-concise-o-log-min-m-n-iterative-solution-with-detailed-explanation

代码实现:

double FindMedianSortedArrays(vector<int>& A, int a_start, vector<int>& B, int b_start,int key)
{
    if (A.size() - a_start > B.size() - b_start) //统一情况,每次假定A的长度小于等于B,这样不用每次操作两种情况:A的长度小于等于B,A的长度大于B;
        return FindMedianSortedArrays(B, b_start, A, a_start, key);

    if (0 == A.size() - a_start) //因为B的长度总是大于等于A,所以若是A的剩余长度为0,那么刚好要找的数就是B中的第key个数
        return B[key - 1];
    if (1 == key)
        return A[a_start] < B[b_start] ? A[a_start] : B[b_start];

    int a_mid = key / 2 < (A.size() - a_start) ? a_start + key / 2 : A.size();  //要定位A的最右边那个数,所以要加上起始位置,不然坐标不对
    int b_mid = key - a_mid + b_start + a_start;   //定位B的最右边那个数


    if (A[a_mid - 1] < B[b_mid - 1])
        return FindMedianSortedArrays(A,a_mid,B,b_start,key - a_mid + a_start);
    else if (A[a_mid - 1] > B[b_mid - 1])
        return FindMedianSortedArrays(A, a_start, B, b_mid, key - b_mid + b_start);
    else
        return A[a_mid - 1];

    return 0;
}
   double findMedianSortedArrays(vector<int> &A, vector<int> &B) 
   {
        int a_len = A.size();
        int b_len = B.size();
        if (a_len <= 0 && b_len <= 0)
            return 0;
        int total_len = a_len + b_len;

        if (total_len % 2 != 0)
            return FindMedianSortedArrays(A, 0, B, 0, total_len / 2 + 1);
        else
            return (FindMedianSortedArrays(A, 0, B, 0, total_len / 2) + FindMedianSortedArrays(A, 0, B, 0, total_len / 2 + 1)) / 2.0;
   }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值