【重点!!!】【二分查找】4.寻找两个正序数组的中位数

题目

法1:二分查找(最优解法)

时间复杂度:O(logMin(m, n)),空间复杂度:O(1)。

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if (nums1.length > nums2.length) {
            int[] tmp = nums1;
            nums1 = nums2;
            nums2 = tmp;
        }
        int m = nums1.length, n = nums2.length;
        // 在nums1的区间[0, m]里查找恰当的分割线
        // 使得nums1[i - 1] ≤ nums2[j] && nums2[j - 1] ≤ nums1[i]

        int totalLeft = (m + n + 1) / 2; // 左 ≥ 右
        int left = 0, right = m; // [left, right)是闭开区间
        while (left < right) {
            int nums1Left = (left + right + 1) / 2; // 是指的nums1分割线左侧元素个数(左 ≥ 右), 对应索引是nums1Left - 1
            int nums2Left = totalLeft - nums1Left;  // 是指的nums2分割线左侧元素个数(左 ≥ 右), 对应索引是nums2Left - 1
            if (nums1[nums1Left - 1] > nums2[nums2Left]) { // nums1的分割线太靠右,需要往左移
                right = nums1Left - 1; // right是取不到的边界, 下次迭代索引nums1Left - 1肯定取不到,故设置right = nums1Left - 1
            } else { // 这里并未直接判断nums2[nums2Left - 1]与nums1[nums1Left]的关系, 故使得nums1[nums1Left]尽量大
                left = nums1Left;      // left是可取到的边界,  下次迭代索引可能取到nums1Left,故设置left = nums1Left
            }
        }
        int i = left, j = totalLeft - left;
        int nums1LeftMax = i == 0 ? Integer.MIN_VALUE : nums1[i - 1];
        int nums1RightMin = i == m ? Integer.MAX_VALUE : nums1[i];
        int nums2LeftMax = j == 0 ? Integer.MIN_VALUE : nums2[j - 1];
        int nums2RightMin = j == n ? Integer.MAX_VALUE : nums2[j];
        int leftMax = Math.max(nums1LeftMax, nums2LeftMax);
        int rightMin = Math.min(nums1RightMin, nums2RightMin);
        if ((m + n) % 2 == 1) {
            return (double) leftMax;
        } else {
            return ((double) leftMax + (double) rightMin) / 2.0;
        }
    }
}
  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值