[lintcode]65. 两个排序数组的中位数[Hard]

描述

两个排序的数组A和B分别含有m和n个数,找到两个排序数组的中位数,要求时间复杂度应为O(log (m+n))。

 

样例

给出数组A = [1,2,3,4,5,6] B = [2,3,4,5],中位数3.5

给出数组A = [1,2,3] B = [4,5],中位数 3

挑战

时间复杂度为O(log n)

思路

本质上是二分查找, 只不过条件比较奇葩。除了思路之外难点还在于特殊情况非常多。不知道大家是怎么在一开始处理这些特殊情况的,我的处理有点杂乱,是case-oriented。

class Solution {
public:
    /*
     * @param A: An integer array
     * @param B: An integer array
     * @return: a double whose format is *.5 or *.0
     */
    int min(int a, int b)
    {
        if(a<b) return a;
        else return b;
    }
    
    int max(int a, int b)
    {
        if(a<b) return b;
        else return a;
    }
    
    double binarySearch(int low, int high, vector<int> A, vector<int> B, int nm2, bool even)
    {

        if(low >= high)
        {
            if(low != A.size()-1)
            {
                if(even)
                {
                    return (double(max(A[low], B[nm2-low]))+double(min(A[low+1],B[nm2-low+1])))/2;
                }
                else
                {
                    return max(A[low], B[nm2-low+1]);
                }
            }
            else
            {
                if(even)
                {
                    return (double(max(A[low], B[nm2-low]))+B[nm2-low+1])/2;
                }
                else
                {
                    return max(A[low], B[nm2-low+1]);
                }
                
            }
        }
        
        int mid = (low+high)/2;

        if(even)
        {
            if(A[mid] > B[nm2-mid+1])
            {
                high = mid-1;
                if(mid == 0)
                {
                    int id = B.size() - (nm2+2 - A.size()) - 1;                    
                    if(id == B.size()-1)
                    {
                        return (double(B[id])+double(A[0]))/2;
                    }
                    else
                    {
                        return (double(B[id])+double(B[id+1]))/2;
                    }
                    return B[id];
                }
                return binarySearch(low, high, A,B, nm2,even);
            }
            else if(B[nm2-mid] > A[mid+1])
            {
                low = mid+1;
                return binarySearch(low, high, A,B, nm2,even);
            }
            else
            {
                return (double(max(A[mid], B[nm2-mid]))+double(min(A[mid+1],B[nm2-mid+1])))/2;
            }
            
        }
        else
        {
            if(A[mid] > B[nm2-mid+2])
            {
                high = mid-1;
                if(mid == 0)
                {
                    int id = B.size() - (nm2+2 - A.size()) - 1;
                    return B[id];
                }
                return binarySearch(low, high, A,B, nm2,even);
            }
            else if(B[nm2-mid+1] > A[mid+1])
            {
                low = mid+1;
                return binarySearch(low, high, A,B, nm2,even);
            }
            else
            {
                return max(A[mid], B[nm2-mid+1]);
            }
            
        }
    }
    
   
    double findMedianSortedArrays(vector<int> &A, vector<int> &B) {
        // write your code here
        /*
        A1,A2,A3..Ai | Ai+1, Ai+2...An
        B1,B2,B3..Bj | Bj+1, Bj+2...Bm
        
        Ai < Bj+1 && Bj < Ai+1
        
        if even=>
        i+j = n+m-i-j => j= (n+m)/2 - i
        
        if odd=>
        i+j+1 = n+m-i-j-1 => j= (n+m)/2 - i-1
        */
        
        int i=0, j=0;
        int n=A.size(), m=B.size();
        bool even=false;
        
        if((n+m) %2 == 0)
        {
            even=true;
        }
        
        if(A.size() == 0)
        {
            if(B.size() == 0)
            {
                // error
            }
            else
            {
                if(even)
                {
                    return (double(B[B.size()/2])+double(B[B.size()/2-1]))/2;
                }
                else
                {
                    return B[B.size()/2];
                }
            }
        }
        else if(B.size() == 0)
        {
            if(A.size() == 0)
            {
                // error
            }
            else
            {
                if(even)
                {
                    return (double(A[A.size()/2])+double(A[A.size()/2-1]))/2;
                }
                else
                {
                    return A[A.size()/2];
                }
            }
        }
            
    
        int lowi = 0;
        int highi = A.size()-1;
        int nm2 = (n+m)/2-2;
        
    
        double ans;
        
        if(n<m)
        {
            ans = binarySearch(lowi, highi, A, B, nm2, even);
        }
        else
        {
            ans = binarySearch(lowi, highi, B, A, nm2, even);
        }
        

        
        return ans;
        
    }
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值