【转】004 寻找两个有序数组的中位数C++版本

【转】 两个有序数组中的中位数和Top K问题

原文链接:原文链接

代码

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size();
        int m = nums2.size();
        if(n > m) {  //保证数组1一定最短,每次都在小的上二分
            return findMedianSortedArrays(nums2,nums1);
        }
        //为了省去奇数偶数的麻烦,
        //为每个数组首尾以及两数之间虚加#
        //例如:  # 2 # 4 # 5 # 7 #
        //因此一共有2m+2n+2个元素
        //因此数量数组元素数量翻倍
       	//L1表示数组1 二分后左边最大元素,R1表示数组1右边最大元素
       	//L2,R2同理
       	//c1 c2 表示数组1和2分割点位置,也是左侧元素的数量
       	//lo和hi是数组1的左边和右边的下标
        int L1,L2,R1,R2,c1,c2,lo = 0, hi = 2*n; 

        while(lo <= hi) {
            c1 = (lo + hi) / 2;  //c1是二分的结果
            c2 = m + n - c1; //理解难点,见下面补充   
            //看下面的注释补充
            L1 = (c1 == 0)   ? INT_MIN : nums1[(c1-1)/2];
            R1 = (c1 == 2*n) ? INT_MAX : nums1[c1/2];
            L2 = (c2 == 0)   ? INT_MIN : nums2[(c2-1)/2];
            R2 = (c2 == 2*m) ? INT_MAX : nums2[c2/2];

            if(L1 > R2)
                hi = c1-1;
            else if(L2 > R1)
                lo = c1+1;
            else
                break;
        }
        return (max(L1,L2)+ min(R1,R2))/2.0;
}

而对于割(Cut),如果割在‘#’上等于割在2个元素之间,割在数字上等于把数字划到2个部分,总是有以下成立:

LMaxi = (Ci-1)/2 位置上的元素
RMini = Ci/2 位置上的元素

如果C1或C2已经到头了怎么办?

这种情况出现在:如果有个数组完全小于或大于中值。假定n<m, 可能有4种情况:

C1 = 0 —— 数组1整体都在右边了,所以都比中值大,中值在数组2中,简单的说就是数组1割后的左边是空了,所以我们可以假定LMax1 = INT_MIN

C1 =2n —— 数组1整体都在左边了,所以都比中值小,中值在数组2中 ,简单的说就是数组1割后的右边是空了,所以我们可以假定RMin1=INT_MAX,来保证LMax2<RMin1恒成立

C2 = 0 —— 数组2整体在右边了,所以都比中值大,中值在数组1中 ,简单的说就是数组2割后的左边是空了,所以我们可以假定LMax2 = INT_MIN

C2 = 2m —— 数组2整体在左边了,所以都比中值小,中值在数组1中, 简单的说就是数组2割后的右边是空了,为了让LMax1 < RMin2 恒成立,我们可以假定RMin2 = INT_MAX

作者:bian-bian-xiong
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/4-xun-zhao-liang-ge-you-xu-shu-zu-de-zhong-wei-shu/
来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

如何理解c2 = m + n - c1
参考yyl9510的回答
为了将nums1和nums2插入#后的2m+2n+2个数平分,拆分过程中其实将c1和c2所在位置的#或数值分成了左右各一份。也就是总数变成了2m+2n+4,其中左边共有c1+1+c2+1个数,右边有(2m-(c1-1)+2n-(c2-1))也就是(2m+2n+2-c1-c2)个数,两边相等即c1+c2+2=2m+2n+2-c1-c2得到c2 = m + n - c1;

参考文献:参考文献

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值