LeetCode-4-寻找两个正序数组的中位数c++

HR面完刚好是周末,没有办法只能焦急的等待腾讯的offer…,为了缓解情绪,继续做做LeetCode还有学学unity。

题目描述

在这里插入图片描述

思路 二分法

跟我们常见的二分法有挺大的区别,但是本质还是不断舍弃一半的数。
困难题都是思路说破就没啥了,但是自己想基本想不出来。
本题思路:
我们把寻找中位数的过程当成寻找第k个数的过程,如果两个数组总长为奇数,只需寻找第k/2 +1个数,如果两个数组总长为偶数,寻找第k/2个数和第k/2 + 1个数。
接下来就是不曾见过的船新二分法了!!
我们设所寻找的数为第n个,设置两个指针index1和index2,一个起始为数组一的0号元素,一个起始为数组二的0号元素。
然后我们每次取包括指针所指元素在内的第n/2个元素,比较两个数组该元素的大小
关键来了,小的那一方的这n/2个元素不可能是第n大的元素。因为第n/2最好情况下都会小于大的那一方的第n/2个,所以它最大也就是第n - 1个,所以我们可以把这n/2个元素排除。
然后被排除的数字就没有意义了,我们就将指针移动到下一个位置,同时n减去排除了几个数字。这里要注意,n/2处可能会大于数组长度,这时候就比较数组最后一个数,最后n也是减去到最后一个元素为止有几个数。

具体例子:windliang
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution {
//思路:
//每次取两个数组的第k/2个数比较,小的那一方的前k/2个数不可能是第k个,舍弃,以此类推直到找到第k个
//求两次,使偶数的时候能找到k/2和k/2+1,奇数的时候能找到两个k/2
public:
    int getK(vector<int> nums1, vector<int> nums2, int k) {
        int len1 = nums1.size();
        int len2 = nums2.size();
        int index1 = 0, index2 = 0;
        while(1) {
            //数组1的元素已经被全部排除,剩下的第k大个个数只能在index2后面的第k个
            //为什么需要-1,因为index本身已经包括一个数字
            //因为index是下一个数,所以会等于数组长度。
            if(index1 == len1) {
                return nums2[index2 + k - 1];
            } 
            if(index2 == len2) {
                return nums1[index1 + k - 1];
            }
            if(k == 1) {
                return min(nums1[index1], nums2[index2]);
            }
            int newIndex1 = min(index1 + k / 2 - 1, len1 - 1);
            int newIndex2 = min(index2 + k / 2 - 1, len2 - 1);
            if(nums1[newIndex1] <= nums2[newIndex2]) {
                //newIndex1到index1之间有几个数字
                k -= newIndex1 - index1 + 1;
                //下一个index从newIndex1的下一个数开始
                index1 = newIndex1 + 1;
            } else {
                k -= newIndex2 - index2 + 1;
                index2 = newIndex2 + 1;
            }
        } 
    }
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int wholeLen = nums1.size() + nums2.size();
        if(wholeLen % 2 == 0) {
            return (getK(nums1, nums2, wholeLen / 2) + getK(nums1, nums2, wholeLen / 2 + 1) )/ 2.0;
        } else {
            return getK(nums1, nums2, wholeLen / 2 + 1);
        }
    }
};

时间复杂度O(log(m+n))
空间复杂的O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值