4. Median of Two Sorted Arrays [Hard]

本文介绍了一种优化的算法,用于在两个有序数组中寻找中位数,仅遍历到中位数位置,避免了完全合并数组。作者分享了两种方法,一种是找到中位数位置后立即停止,另一种是通过对比指针移动合并数组。讲解了如何利用mid1和mid2确定中位数,简化了逻辑判断。

生成一个合并数组:

分别用两个指针从两个数组的首部开始遍历,将两指针所指向元素中较小的加入合并数组,并指向该元素的指针该指针向后移动

题目只要求中位数,因此将合并数组完全生成再找中位数固然可以,但也可以将数组合并到中位数的位置就停下来,后者能提前结束循环,但逻辑判断会复杂一些

求中位数:

中位数可能是一个数也可能是两个数的平均值,看到很多答案都用了比较复杂的分情况讨论

我用的方法是求出mid1和mid2两个位置,无论什么情况下都返回这两个位置数的平均值

如果是一个数,mid1会等于mid2,都指向最中间的数,平均值仍是自身,即中位数;

如果是两个数,mid1 + 1 = mid2,指向中间的两个数,求平均值就是中位数。

有空可以看下这个,O(logn)解法?https://leetcode.com/problems/median-of-two-sorted-arrays/discuss/2481/Share-my-O(log(min(mn)))-solution-with-explanation

/**
 * 自己的代码
 * 只找到中位数的位置就停下,情况稍微复杂一些,后面的判断多,但能省去把整个数组排完浪费的资源
 */
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int length = nums1.length + nums2.length;
        int[] nums = new int[length];
        int p1 = 0, p2 = 0, idx = 0, mid1 = (length - 1) / 2, mid2 = length / 2;
        while (p1 < nums1.length && p2 < nums2.length && idx < mid2 + 1)
            if (nums1[p1] > nums2[p2])
                nums[idx++] = nums2[p2++];
            else
                nums[idx++] = nums1[p1++];
        if (idx == mid2 + 1)
            return (nums[mid1] + nums[mid2]) / 2.0;
        if (p1 == nums1.length)
            if (p1 + p2 <= mid1 || p1 == 0)
                return (nums2[mid1 - p1] + nums2[mid2 - p1]) / 2.0;
            else
                return (nums[mid1] + nums2[mid2 - p1]) / 2.0;
        else
            if (p1 + p2 <= mid1 || p2 == 0)
                return (nums1[mid1 - p2] + nums1[mid2 - p2]) / 2.0;
            else
                return (nums[mid1] + nums1[mid2 - p2]) / 2.0;
    }
}
/**
 * 把整个数组排完的做法,代码比较简洁
 */
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int length = nums1.length + nums2.length;
        int[] nums = new int[length];
        int p1 = 0, p2 = 0, idx = 0, mid1 = (length - 1) / 2, mid2 = length / 2;
        while (p1 < nums1.length && p2 < nums2.length)
            if (nums1[p1] > nums2[p2])
                nums[idx++] = nums2[p2++];
            else
                nums[idx++] = nums1[p1++];
        while (p1 < nums1.length)
            nums[idx++] = nums1[p1++];
        while (p2 < nums2.length)
            nums[idx++] = nums2[p2++];
        return (nums[mid1] + nums[mid2]) / 2.0;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值