码迷,mamicode.com
首页 > 编程语言 > 详细

leetcode 4. 寻找两个正序数组的中位数

时间:2020-06-20 13:39:53      阅读:85      评论:0      收藏:0      [点我收藏+]

标签:kth   -o   amp   中位数   第一个   直接   ndk   return   code   

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

给定两个大小为 m 和 n 的正序(从小到大)数组?nums1 和?nums2。

请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为?O(log(m + n))。

你可以假设?nums1?和?nums2?不会同时为空。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
技术图片

解题思路:
寻找数组中的中位数,即转化为寻找有序数组的第k小数问题(第k小的数即为中位数)
题目要求时间复杂度o(log(m+n))显然采用二分法,此题采用是折半删除找第k小数
技术图片
问题:为什么可以直接删除第一个数组中的前k/2个数呢?
我们要寻找的是当前两个有序数组中的第k小的数,显然通过比较可以判断出剔除的k/2个数一定在第k小数的左边 可以直接剔除
证明:
设两个数组总元素个数为n
因为数组为有序递增数组,要证明所剔除的数都在第k小数左边,只需证明剔除的数中的最大数在第k小数的左边,即证明在该数右边的元素个数大于等于(n-k+1)
因为nums1[k/2-1]<nums2[k/2-1]时,两个数组中至少有n-(k/2)2+1个数大于等于nums1[k/2-1]
又因为k>=(k/2)
2
所以n-(k/2)*2+1>=n-k+1
所以在nums1[k/2-1]右边的元素个数大于等于(n-k+1)
所以我们是可以直接剔除那些数的

不断进行折半剔除,直到k=1时,即中位数是当前数组剩余数中的最小数时,直接比较两个数组中当前的第一个数(即最小数)取较小的数即为中位数
代码如下

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n=nums1.size(),m=nums2.size();
        int k1=(n+m+1)/2,k2=(n+m+2)/2;//当n+m为奇数时k1=k2;
        return (findKth(nums1,0,n-1,nums2,0,m-1,k1)+findKth(nums1,0,n-1,nums2,0,m-1,k2))/2.0;//当n+m为奇数时即取到的同一个数,n+m为偶数即两个数取平均
    }
    int findKth(vector<int>&nums1,int le1,int ri1,vector<int>&nums2,int le2,int ri2,int k){
        int length1=ri1-le1+1;
        int length2=ri2-le2+1;
        if(length1>length2) return findKth(nums2,le2,ri2,nums1,le1,ri1,k);//保证第一个数组比第二个数组短
        if(length1==0) return nums2[le2+k-1];//当第一个数组为空时,直接从第二个数组取第k小数
        if(k==1) return min(nums1[le1],nums2[le2]); 
        int i=min(k/2,length1);
        int j=min(k/2,length2);
        if(nums1[le1+i-1]>nums2[le2+j-1]){
            return findKth(nums1,le1,ri1,nums2,le2+j,ri2,k-j);
        }
        else{
            return findKth(nums1,le1+i,ri1,nums2,le2,ri2,k-i);
        }
    }
};

leetcode 4. 寻找两个正序数组的中位数

标签:kth   -o   amp   中位数   第一个   直接   ndk   return   code   

原文地址:https://www.cnblogs.com/zhangfeng406/p/13168276.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!