2011年408真题42题 求两个升序数组的中位数

题目

题目

思路

1、假定S1中存在中位数,则可用二分的方式来枚举,设为S1[mid],即S1中下标为mid的数
2、在S2中二分找到最后一个小于等于中位数S1[mid]的位置mid2
3、此时,注意到S1的[0,mid]S2的[0,mid2],他们均小于等于S1[mid],且因为数组是非递减的,故而剩下的数都大于等于S1[mid]
4、计算S1[0,mid]S2[0,mid2]的长度 len = mid + 1 + L2 + 1 ,设一个数组长度为n,则:
(1)若len == n,说明找到了,直接返回S1[mid]
(2)若len > n,说明中位数太大了
(3)若len < n,说明中位数太小了
5、若S1找完了,跳出二分查找了,还是没有找到,则说明中位数在S2,此时,讲S1与S2调换再来一遍即可

复杂度

时间复杂度:O(2 * log2(n) * log2(n))
空间复杂度:O(1)

相关资料

这里贴一个链接,有这道题目更全面的信息: 408史上最难算法题:两个升序数组的中位数

C++ 代码

class Solution {
    int find(vector<int>& S1 , vector<int>& S2) {
        int n = S1.size();
        int L1 = 0, R1 = S1.size() - 1;
        while (L1 <= R1) { // 二分检查每个可能的中位数
            int mid = (L1 + R1) >> 1;
            int L2 = 0, R2 = S2.size() - 1;
            while (L2 < R2) { // 在S2中二分查找小于等于中位数S1[mid]的数的个数
                int mid2 = (L2 + R2 + 1) >> 1;
                if (S2[mid2] > S1[mid]) R2 = mid2 - 1;
                else L2 = mid2;
            }
            if (S2[L2] > S1[mid]) L2--; // 说明一个都没找到,S2全都大于中位数
            int len = mid + 1 + L2 + 1; // S1与S2中数的总数
            if (len == n) return S1[mid];
            else if (len > n) R1 = mid - 1;
            else L1 = mid + 1;
        }
        return INT_MIN; // 作为没找到答案的标志
    }
public:
    int medianSearch(vector<int>& S1 , vector<int>& S2) {
        int ret = find(S1, S2);
        if (ret != INT_MIN) return ret;
        return find(S2, S1); // 第一次没找到就反过来再找一次
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值