LeetCode——Median of Two Sorted Arrays

本文介绍了一种高效算法,用于查找两个已排序数组合并后的中位数。通过递归划分,逐步缩小搜索范围,最终在O(log(min(m, n)))的时间复杂度内找到答案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Median of Two Sorted Arrays Mar 28 '11 2878 / 15149


There are two sorted arrays A and B 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)).

» Solve this problem

将题目转换为 求两个有序数组合并后的第K个数

如何在合并后的数组中找出第K个数:

先看一个实际的例子:

A={0,1,2,3,4,5,6}

B={2,4,6,8}


取出A、B中间的数,即A3=3,B1=4。

因为A3<=B1,所以我们可以肯定A0、A1、A2也是小于等于B1的,同时B0也小于等于B1。

因此可得,B1在合并后的数组中至少是第6个数(能确定这五个数:A0、A1、A2、A3、B0小于等于B1,不能确定A4、A5、A6与B1的关系)。

同理可知,A3在合并后的数组中至多是第5个数(A3<=A4<=A5<=A6,A3<=B1<=B2<=B3,不能确定A3与B0的关系)。


如果K<=5,那么所求答案必然在A0~A7以及B0中间(B1及B1之后的数都至少是第6个数)。

如果K>5,那么所求答案必然在A4~A7以及B0~B3中间(A3及A3之前的数都至多是第5个数)。

整个算法的雏形也就出来了。

// 针对上例
lA = 0, rA = 6; 
lB = 0, rB = 3;
while (lA <= rA && lB <= rB) {
    midA = (lA + rA) / 2;
    midB = (lB + rB) / 2;
    if (A[midA] <= B[midB]) {
        if (k <= midA - lA + midB - lB + 1) {
            rB = midB - 1;
        }
        else {
            k -= midA - lA + 1;
            lA = midA + 1;
        }
    }
    else {
        if (k <= midA - lA + midB - lB + 1) {
            rA = midA - 1;
        }
        else {
            k -= midB - lB + 1;
            lB = midB + 1;
        }
    }
}
if (lA <= rA) {
    ans = A[lA + k - 1];
}
else {
    ans = B[lB + k - 1];
}


P.S.

该题是找中位数。所以如果长度为偶数,需要找出中间的两个数,相加除以2。

例如:A={1, 2, 3, 4}, B={5, 6}, 则借为(3+4) / 2 = 3.5。

因此,

对于本题,假设合并后的长度为L:

1.L为奇数,则K=(L+1)/2;

2.L为偶数,则K1=L/2,K2=L/2+1。


class Solution {
public:
    double findMedianSortedArrays(int A[], int m, int B[], int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (((m + n) & 1) == 0) {
            double v1 = findKstSortedArrays(A, m, B, n, (m + n) >> 1);
            double v2 = findKstSortedArrays(A, m, B, n, ((m + n) >> 1) + 1);
            return (v1 + v2) / 2;
        }
        else {
            return findKstSortedArrays(A, m, B, n, (m + n + 1) >> 1);
        }
    }
    
    double findKstSortedArrays(int A[], int m, int B[], int n, int k) {
        int l1 = 0, r1 = m - 1;
        int l2 = 0, r2 = n - 1;
        int mid1 = 0, mid2 = 0;
        
        while (l1 <= r1 && l2 <= r2) {
            mid1 = (l1 + r1) / 2;
            mid2 = (l2 + r2) / 2;
            if (A[mid1] <= B[mid2]) {
                if (k <= mid1 - l1 + mid2 - l2 + 1) {
                    r2 = mid2 - 1;
                }
                else {
                    k -= mid1 - l1 + 1;
                    l1 = mid1 + 1;
                }
            }
            else {
                if (k <= mid1 - l1 + mid2 - l2 + 1) {
                    r1 = mid1 - 1;
                }
                else {
                    k -= mid2 - l2 + 1;
                    l2 = mid2 + 1;
                }
            }
        }
        
        if (l1 <= r1) {
            return A[l1 + k - 1];
        }
        else {
            return B[l2 + k - 1];
        }
    }
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值