LeetCode 4:寻找两个正序数组的中位数 —— 二分查找法

LeetCode 4:寻找两个正序数组的中位数 ------ 二分查找法 题解

🔗 题目链接

👉 https://leetcode.cn/problems/median-of-two-sorted-arrays/

📖 题目概要

给定两个大小分别为 mn正序(从小到大)数组 nums1nums2
请你找出并返回这两个正序数组的
中位数

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

示例 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

✅ 本题解法:二分切割法(最优解,AC代码)

核心思想

  1. 不合并数组 ,直接在两个数组上做二分查找
  2. 将两个数组左右切割,让左半部分整体 ≤ 右半部分
  3. 通过切割位置直接算出中位数
  4. 始终把短数组作为 nums1,减少二分次数

💡 详细解题思路

1. 核心原理:数组切割

把两个数组各分成左右两部分:

  • nums1 左:[0, i-1],右:[i, m-1]
  • nums2 左:[0, j-1],右:[j, n-1]

满足两个条件:

  1. 左半总长度 = 右半总长度(或多1)
    i + j = m - i + n - j + 1
    → 推导得:j = (m + n + 1) / 2 - i
  2. 左边所有数 ≤ 右边所有数
    nums1[i-1] ≤ nums2[j]nums2[j-1] ≤ nums1[i]

2. 边界处理

  • 左边没数:用 Integer.MIN_VALUE
  • 右边没数:用 Integer.MAX_VALUE

3. 中位数计算

  • 总长度奇数:左边最大值就是中位数
  • 总长度偶数:(左边最大值 + 右边最小值) / 2.0

4. 二分调整切割点

  • nums1[i-1] > nums2[j]i 太大 → 左移 r = i - 1
  • nums2[j-1] > nums1[i]i 太小 → 右移 l = i + 1

✅ AC 代码

java 复制代码
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; //元素少的数组
        int n = nums2.length;

        int l = 0, r = m;
        while(l <= r) {
            int i = (l + r) / 2;
            int j = (m+n+1) / 2 - i; //绳子总长减去i的长度
            int l1 = (i==0) ? Integer.MIN_VALUE : nums1[i-1];
            int r1 = (i==m) ? Integer.MAX_VALUE : nums1[i];
            int l2 = (j==0) ? Integer.MIN_VALUE : nums2[j-1];
            int r2 = (j==n) ? Integer.MAX_VALUE : nums2[j];
            // 满足条件
            if (l1<=r2 && l2<=r1) {
                if((m+n) % 2 == 1) {
                    return Math.max(l1,l2);
                } else {
                    return (Math.max(l1,l2) + Math.min(r1,r2)) / 2.0;
                }
            } else if(l1 > r2) {
                r = i - 1;
            } else {
                l = i + 1;
            }
        }
        return 0;
    }
}

⏱️ 复杂度分析

指标 复杂度 说明
时间复杂度 O(log(min(m,n))) 只对短数组二分
空间复杂度 O(1) 只用常数变量

📌 核心一句话总结

在两个有序数组上做二分切割,让左边整体 ≤ 右边,满足长度平衡后,直接从边界值计算中位数。


📝 高频面试问答

1. 为什么要把短数组放前面?

让二分次数变少,保证时间复杂度 O(log(min(m,n)))

2. 为什么 j 这么算?

j = (m + n + 1) / 2 - i

保证左右两边长度相等或左边多1,方便取中位数。

3. 为什么要用 MIN/MAX 处理边界?

防止数组越界,同时不影响大小比较。

最后记录一下,第一遍刷完Leetcode的Hot100题。虽然有一些题是抄题解的。

相关推荐
咖啡八杯1 小时前
GoF设计模式——解释器模式
java·后端·spring·设计模式
GuWenyue1 小时前
传统Agent工具两大痛点!300行代码落地MCP跨语言工具,彻底解耦LLM与工具
前端·人工智能·算法
优橙教育1 小时前
5G网优培训 vs Java开发:转行选哪个?
java·开发语言·5g
糖果店的幽灵1 小时前
【DeepAgents 从入门到精通】Context Management 上下文管理
java·人工智能·后端·spring·中间件·langgraph·deepagents
我叫洋洋2 小时前
C ++ [ hello world ]
c语言·c++·算法
腻害兔3 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:字典、短信、邮件、通知——后台系统的“基础设施四件套“!
java·前端·vue.js·产品经理·ai编程
碎光拾影3 小时前
ARM交叉工具链各工具作用及IMX6ULL平台LED+蜂鸣器裸机程序实现
java·开发语言·数据库
奋发向前wcx3 小时前
y1,y2总复习笔记5 2026.7.19
数据结构·笔记·算法
Miao121314 小时前
微服务 API 测试实践:海外某民宿平台如何构建模式驱动测试基础设施
java·开发语言
腻害兔4 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:支付模块 yudao-module-pay,一个让产品经理都看懂的支付中台设计
java·前端·vue.js·产品经理·ai编程