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

一、题目

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

输入:nums1 = [], nums2 = [1]
输出:1.00000

二、解法

问题实际上是求两个正序数组的第k小的数。
简单的思路是双指针一个一个往后移动,时间复杂度是 O ( m + n ) O(m+n) O(m+n),要达到 O ( l o g ( m + n ) ) O(log(m+n)) O(log(m+n)) 的复杂度,必然是每次要减少一半的元素。

n u m s 1 nums1 nums1 n u m s 2 nums2 nums2 数组分别找到前 k / 2 k/2 k/2 个元素,一共是 k k k 或者 k − 1 k-1 k1 个元素。比较 n u m s 1 [ k / 2 − 1 ] nums1[k/2-1] nums1[k/21] n u m s 2 [ k / 2 − 1 ] nums2[k/2-1] nums2[k/21] 的大小,小的那个数,它最多只能比 ( k / 2 − 1 ) + ( k / 2 − 1 ) = k − 2 (k/2-1)+(k/2-1)=k-2 (k/21)+(k/21)=k2 个数大,即它最多只可能是第 k − 1 k-1 k1 小的数,故这个数和它前面的 k / 2 − 1 k/2-1 k/21 个数均可以排除掉。

排除掉后,需要更新 k k k

还需要考虑边界情况:

  • k = 1 k=1 k=1:第一个较小元素即可
  • i + k / 2 − 1 i+k/2-1 i+k/21 越界:直接去另一个数组返回下标即可
class Solution {
public:
    int findKthElement(vector<int>& nums1,vector<int>& nums2,int k){
        int m=nums1.size(),n=nums2.size();
        int i1=0,i2=0;
        while(true){      
            //bounary situation
            if(i1==m){
                return nums2[i2+k-1];
            }
            if(i2==n){
                return nums1[i1+k-1];
            }
            if(k==1){
                return min(nums1[i1],nums2[i2]);
            }

            //normal situation
            int n1=min(i1+k/2-1,m-1);
            int n2=min(i2+k/2-1,n-1);
            if(nums1[n1]<=nums2[n2]){
                k-=(n1-i1+1);
                i1=n1+1;
            }else{
                k-=(n2-i2+1);
                i2=n2+1;
            }
            
        }
    }

    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m=nums1.size(),n=nums2.size();
        if((m+n)%2==1){
            return (double)findKthElement(nums1,nums2,(m+n)/2+1);
        }else{
            cout<<findKthElement(nums1,nums2,(m+n)/2)<<endl;
            cout<<findKthElement(nums1,nums2,(m+n)/2+1)<<endl;
            return ((double)findKthElement(nums1,nums2,(m+n)/2)+(double)findKthElement(nums1,nums2,(m+n)/2+1))/2;
        }
    }
};

你可能感兴趣的:(leetcode,100题,leetcode,算法)