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

好久不做题,脑子都木了

题目链接

这道题需要有技巧的二分

首先确认一下中位数的含义:表示在有序数列中处于中间位置的数,于是有两个性质:

  • 位于中位数左右两侧的数应该满足 数量相等 这一要求。
  • LeftMax < RightMin,也就是左侧最大的数要小于右侧最小的数。

现在我们有两个数组 A A A B B B,如果我们在 A A A 数组查找到了第 i i i 个数,那么为了满足 数量相等 条件, B B B 数组中的查找位置 j j j 是可以确定的,也就是 j = m + n + 1 2 − i j=\frac{m+n+1}{2}-i j=2m+n+1i(整数除法)。这里要注意一个点, A A A 必须是较短的那个数组,否则可能 j j j 会出现负数。

现在我们来尝试确定如何进行二分。已知 A [ i − 1 ] < A [ i ] A[i-1]<A[i] A[i1]<A[i], B [ j − 1 ] < B [ j ] B[j-1]<B[j] B[j1]<B[j]

  1. A [ i − 1 ] > B [ j ] A[i-1]>B[j] A[i1]>B[j],则不满足 LeftMax < RightMin,于是 i i i 应该左移,也就是修改右端点
  2. A [ i − 1 ] < B [ j ] A[i-1]<B[j] A[i1]<B[j],则修改左端点
  3. A [ i − 1 ] = B [ j ] A[i-1]=B[j] A[i1]=B[j],可以合并到上面两种情况中去。

最后的答案根据数组的奇偶性分为两种:

  • 若为奇数则答案是 LeftMax
  • 若为偶数则答案是 (LeftMax + RightMin) / 2

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if (nums1.length > nums2.length) {
            return findMedianSortedArrays(nums2, nums1);
        }

        int m = nums1.length;
        int n = nums2.length;
        int left = 0, right = m;
        int leftMax = 0, rightMin = 0;

        while (left <= right) {
            int i = (left + right) / 2;
            int j = (m + n + 1) / 2 - i;

            int nums_im1 = (i == 0 ? Integer.MIN_VALUE : nums1[i - 1]);
            int nums_i   = (i == m ? Integer.MAX_VALUE : nums1[i]);
            int nums_jm1 = (j == 0 ? Integer.MIN_VALUE : nums2[j - 1]);
            int nums_j   = (j == n ? Integer.MAX_VALUE : nums2[j]);

            if (nums_im1 < nums_j) {
                leftMax = Math.max(nums_im1, nums_jm1);
                rightMin = Math.min(nums_i, nums_j);
                left = i + 1;
            } else {
                right = i - 1;
            }
        }

        if ((m + n) % 2 == 0) return (leftMax + rightMin) / 2.0;
        return leftMax;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SP FA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值