寻找两个正序数组的中位数

分析:

  • 对于两个有序序列, 要求log(n+m) 求出, 那么就优先二分, 其次由于有单调性,所以再次确认是二分。
  • 对于两个有序序列, 如何一次能用二分来排除一部分的数, 我们就可以轻而易举 的想到 如果都取中值, 那么就可以更新二分中点, 并且删除 某个log 个数的数。

在这里插入图片描述

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int tot = nums1.size() + nums2.size();
        if(tot %2 == 0) // 如果一共有偶数个,中位数就是两个之和除二
        {
            int first = findKthNumber(nums1, 0, nums2, 0, tot/2);
            int second = findKthNumber(nums1, 0, nums2, 0, tot/2+1);
            return (first + second) / 2.0;
        }
        else
        {
            return findKthNumber(nums1, 0, nums2, 0, tot/2+1); // 奇数就是中间的一个数
        }
    }

    // 找到第k个数字, i表示nums1从第i个开始, j表示nums2从第j个开始,找两个序列合并的第k个数
    int findKthNumber(vector<int> &nums1, int i, vector<int> &nums2, int j, int k)
    {
        // 如果nums1中的剩余元素更多的话, 交换下nums1和nums2
        // 目的是让nums1中的剩余元素少, nums2中剩余元素多, 这样好处理后续的
        if(nums1.size() - i > nums2.size() - j) return findKthNumber(nums2, j, nums1, i, k);
        
        // 如果nums1没有元素 那么两个合并的第k大,就是nums2 的第k大
        if(nums1.size() == i) return nums2[j+k-1];

        // 如果找的剩下一个数, 那就是两个序列中小的那一个
        if(k == 1) return min(nums1[i], nums2[j]); 

        // 这里si取min 是因为可能si加上k/2个就可能超出范围。
        // 这里加k/2 就是要更新一下i和j 的新位置
        int si = min(i+k/2, int(nums1.size())) , sj = j+k/2;

        if(nums1[si-1] > nums2[sj - 1])
        {
            // 递归下去, 因为nums1的更大,所以nums2的前k/2个元素就没有用了
            // 所以更新nums2的新起点, 更新要找的值
            return findKthNumber(nums1, i, nums2, j+k/2, k-k/2);
        }
        else
        {
            return findKthNumber(nums1, si, nums2, j, k-(si-i));
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值