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题。虽然有一些题是抄题解的。

相关推荐
白远山6 小时前
上海24小时自助健身房系统软件开发实战指南
java·架构·uni-app·需求分析
泡海椒6 小时前
jquick-pdf 表格实战:动态数据 PDF 报表生成
java·开发语言·pdf
天真小巫6 小时前
2026.9.19总结
职场和发展
reikocao6 小时前
大场景下 Hessian 特征值放大与退化检测
算法
hetao17338376 小时前
2026-09-18 hetao1733837 的刷题记录
c++·算法
OxYGC6 小时前
[AI工程] Spring AI 第十四篇:Agent 五种模式在 2.0 里怎么写
java·spring·ai·ai编程
code2cat6 小时前
【随笔】从聊天到调用工具:理解MCP在AI应用中的位置
java·人工智能
2501_933923256 小时前
Spring Bean作用域揭秘:单例、原型、请求与会话的区别
java·后端·spring·java-ee
wuyk5556 小时前
21.计数排序:不用比较的“空间换时间”排序算法
python·算法·排序算法
学编程就要猛6 小时前
基于Spring AI 的智能聊天机器人
java·spring ai·chat robot