【数组】两个排序数组的中位数Median of Two Sorted Arrays

题目:找到两个排序数组的中位数, 两个数组大小分别是m和n, 要求时间复杂度是O(log(m+n))


中位数:数组长度是奇数,则中位数是中间值;数组长度是偶数,则中位数是中间两个数的算术平均值


例如:nums1 = [1, 3], nums2 = [2], 则中位数是2;nums1 = [1, 2], nums2 = [3, 4], 则中位数是(2+3)/2 = 2.5.


此题的核心思想是找到两个数组的第K大的数,具体到这个题,则是找到第(m+n+1)/2,以及第(m+n+2)/2,然后求他们的平均值


找两个排序数组第K大元素C++程序如下:

//两个数组A和B,la和lb分别表示数组的比较起始点,k表示需要寻找的顺序k
int findKth(vector<int>& A,int la, vector<int>& B, int lb,int k){
    if(A.size()-la<B.size()-lb) 
        return findKth(B, lb, A, la, k); //将较长的数组放在前面
    if(lb == B.size()) return A[la+k-1];
    if(k==1) return min(A[la], B[lb]);
    
    int kb = k/2<B.size()-lb?k/2:B.size()-lb;
    int ka = k - kb;
    if(A[la+ka-1]<B[lb+kb-1]){
        return findKth(A, la+ka, B, lb, k-ka);
    }else
        return findKth(A, la, B, lb+kb, k-kb);
}


此题还有优化空间,算法复杂度可优化至O(log(min(m,n))),参考程序(https://discuss.leetcode.com/topic/16797/very-concise-o-log-min-m-n-iterative-solution-with-detailed-explanation/2)如下

 double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
    int N1 = nums1.size();
    int N2 = nums2.size();
    if (N1 < N2) return findMedianSortedArrays(nums2, nums1);	// Make sure A2 is the shorter one.
    
    if (N2 == 0) return ((double)nums1[(N1-1)/2] + (double)nums1[N1/2])/2;  // If A2 is empty
    
    int lo = 0, hi = N2 * 2;
    while (lo <= hi) {
        int mid2 = (lo + hi) / 2;   // Try Cut 2 
        int mid1 = N1 + N2 - mid2;  // Calculate Cut 1 accordingly
        
        double L1 = (mid1 == 0) ? INT_MIN : nums1[(mid1-1)/2];	// Get L1, R1, L2, R2 respectively
        double L2 = (mid2 == 0) ? INT_MIN : nums2[(mid2-1)/2];
        double R1 = (mid1 == N1 * 2) ? INT_MAX : nums1[(mid1)/2];
        double R2 = (mid2 == N2 * 2) ? INT_MAX : nums2[(mid2)/2];
        
        if (L1 > R2) lo = mid2 + 1;		// A1's lower half is too big; need to move C1 left (C2 right)
        else if (L2 > R1) hi = mid2 - 1;	// A2's lower half too big; need to move C2 left.
        else return (max(L1,L2) + min(R1, R2)) / 2;	// Otherwise, that's the right cut.
    }
    return -1;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值