LeeCode4:求两个有序数组的中位数

求两个有序数组的中位数,要求时间复杂度是O(log(m+n)),m+n是两个数列的长度之和
在网上参考了大神的解法,真的太棒了,本菜鸡只会说一句卧*,和大家分享一下。求中位数就是求第k小数的一种特殊情况而已,下面详细介绍求第k小数的算法

现在假设s1={1,3,4,9},s2={1,2,3,4,5,6,7,8,9,10},而我们要求的是第7小的数,即K=7,那么我们可以这样。

第一步 求k/2

此时我们找到两个数列的第三小的数字,因为3<4,我们可以判断第7小的数一定不在s2的3之前。于是我们的比较缩小了,下一次从s2的4开始比较,前面三位不用管

第二步 此时k变为k=7-3=4,因为删去了三个数,这三个数小于第7小的数。
在这里插入图片描述
步骤和1类似

第三步 k=4-2=2
在这里插入图片描述
这时4和4相等,统一删去s2的4,那么

第四步 此时k=1,注意k=1是我们递归跳出的条件之一。这时候我们比较指针所指位置,返回较小的数即可,那么答案就是s1的4

若干其他情况
1.如果数组的长度s1<k/2,那么这个时候,我们直接将s1的比较指针指向s1的最后一个元素即可,如果最后s1全都被删去了,那么我们直接返回s2中的第(k-s1.length)个元素即可,例如在这里插入图片描述
此时直接返回s2的第五个元素
2.为了统一,我们要保证s1的长度小于s2的长度,原因见代码注释

代码!!!

注意!!!这里给的是求中位数的算法

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    
    
    int n = nums1.length;
    int m = nums2.length;
    int left = (n + m + 1) / 2;
    int right = (n + m + 2) / 2;
    //将偶数和奇数的情况合并,如果是奇数,会求两次同样的 k 。
    return (getKth(nums1, 0, n - 1, nums2, 0, m - 1, left) + getKth(nums1, 0, n - 1, nums2, 0, m - 1, right)) * 0.5;  
}
    
    private int getKth(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k) {
    
    
        int len1 = end1 - start1 + 1;
        int len2 = end2 - start2 + 1;
        //让 len1 的长度小于 len2,这样就能保证如果有数组空了,一定是 len1
        if (len1 > len2) return getKth(nums2, start2, end2, nums1, start1, end1, k);
        if (len1 == 0) return nums2[start2 + k - 1];
    //如果len1为空的话,直接返回
        if (k == 1) return Math.min(nums1[start1], nums2[start2]);
      //如果取第1小的数,那么取两个数组第一个元素的最小值
        int i = start1 + Math.min(len1, k / 2) - 1;
        //从start到第k小的数,注意要-1
        int j = start2 + Math.min(len2, k / 2) - 1;
//如果数组长度小于k/2的话则指向最后一个元素
        if (nums1[i] > nums2[j]) {
    
    
            return getKth(nums1, start1, end1, nums2, j + 1, end2, k - (j - start2 + 1));
        }
        else {
    
    
            return getKth(nums1, i + 1, end1, nums2, start2, end2, k - (i - start1 + 1));
        }
    }


总结

遇到时间复杂度为对数的题,基本可以确定用二分法,本题中相当于对s1和s2轮流减半,即O(log(m+n))

猜你喜欢

转载自blog.csdn.net/qq_43406565/article/details/105054190