其他分享
首页 > 其他分享> > 4. 寻找两个正序数组的中位数(找第K小数)

4. 寻找两个正序数组的中位数(找第K小数)

作者:互联网

1.Description

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

算法的时间复杂度应该为 O(log (m+n)) 。

2.Example

示例 1:

输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2


示例 2:

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

3.My Code(投机取巧)

使用merge之前需要先指定好目标vector的size,才能够merge操作;取中位数要乘1.0转为浮点数

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        vector<int>nums3(nums1.size()+nums2.size());
        merge(nums1.begin(),nums1.end(),nums2.begin(),nums2.end(),nums3.begin());
        sort(nums3.begin(),nums3.end());
        if(nums3.size()%2==1)
            return nums3[nums3.size()/2];
        return  (nums3[nums3.size()/2]*1.0 + nums3[nums3.size()/2-1]*1.0)/2;
    }
};

4.Code(正解)

难度主要在于实现O(log(m+n))的复杂度,使用查找第K个数的思想,注意边界情况。

复杂度的要求有log的,通常都需要用到二分查找,这道题也可以通过二分查找实现。

题解:查找第K小的数力扣icon-default.png?t=M1L8https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xun-zhao-liang-ge-you-xu-shu-zu-de-zhong-wei-s-114/

#include<algorithm>
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n1 = nums1.size();
        int n2 = nums2.size();
        if((n1+n2)%2==1)
            return findKthNum(nums1,nums2,(n1+n2)/2+1);
        return (findKthNum(nums1,nums2,(n1+n2)/2+1)*1.0 + findKthNum(nums1,nums2,(n1+n2)/2)*1.0)/2;
    }

    //这是里的k是从1算起,就是找第k小的数
    int findKthNum(vector<int>& nums1, vector<int>& nums2,int k){
        int idx1=0,idx2=0;
        int len1 = nums1.size();
        int len2 = nums2.size();
        while(true){
            //边界问题
            //选取两个数组剩余元素的第一个中最小的
            if(k==1)
                return min(nums1[idx1],nums2[idx2]);
            //nums1已经没有元素可以删除了
            if(nums1.size() == idx1)
                return nums2[idx2+k-1];
            if(nums2.size() == idx2)
                return nums1[idx1+k-1];
            
            //递增idx1,idx2,进行元素删除
            int index1 = min(len1 -1,idx1 + k/2 -1);
            int index2 = min(len2 -1,idx2 + k/2-1);
            if(nums1[index1]>=nums2[index2]){
                k -= index2 - idx2+1;
                idx2 = index2 +1;
            }else{
                k -= index1 - idx1+1;
                idx1 = index1 +1;
            }
        }
    }
};

5.思路

1.注意:这里的K一直都是从1算起的(nums[0]为第1小的元素),每次需要比较的是nums[index + k/2 -1],需要注意是否会数组越界。

2.三种边界情况需要注意。

3. 注意:在如min(nums.size(),k/2)中,会提示找不到对应的min函数,因为这里nums.size()为size_type类型,需要转化为int类型才能够使用min函数来对比。

标签:正序,int,nums3,中位数,idx2,小数,nums1,nums2,size
来源: https://blog.csdn.net/badmer/article/details/123108365