Today is a Saturday Deep Dive day. The full deep dive content has been written to the deepdive archive file.
Individual section summaries are not generated on Saturdays — see the deepdive file for comprehensive content covering the selected topic in full bilingual detail.
Deep dive topic: Median of Two Sorted Arrays (LeetCode #4)
Date: 2026-05-09
Saturday Deep Dive Day
Today is a Saturday Deep Dive day. The full deep dive content has been written to the deepdive archive file.
Individual section summaries are not generated on Saturdays — see the deepdive file for comprehensive content covering the selected topic in full bilingual detail.
Deep dive topic: Median of Two Sorted Arrays (LeetCode #4)
Date: 2026-05-09
Saturday Deep Dive Day
Today is a Saturday Deep Dive day. The full deep dive content has been written to the deepdive archive file.
Individual section summaries are not generated on Saturdays — see the deepdive file for comprehensive content covering the selected topic in full bilingual detail.
Deep dive topic: Median of Two Sorted Arrays (LeetCode #4)
Date: 2026-05-09
Saturday Deep Dive Day
Today is a Saturday Deep Dive day. The full deep dive content has been written to the deepdive archive file.
Individual section summaries are not generated on Saturdays — see the deepdive file for comprehensive content covering the selected topic in full bilingual detail.
Deep dive topic: Median of Two Sorted Arrays (LeetCode #4)
Date: 2026-05-09
Saturday Deep Dive Day
Today is a Saturday Deep Dive day. The full deep dive content has been written to the deepdive archive file.
Individual section summaries are not generated on Saturdays — see the deepdive file for comprehensive content covering the selected topic in full bilingual detail.
Deep dive topic: Median of Two Sorted Arrays (LeetCode #4)
Date: 2026-05-09
🔬 Saturday Deep Dive: Median of Two Sorted Arrays — The Hardest Easy Concept (15 min read)
This is LeetCode #4 — one of the most notoriously tricky Hard problems in the entire NeetCode 150. The naive approach (merge + find middle) is O(m+n) and trivial. The interviewer wants O(log(min(m,n))). That constraint forces you to think about binary search not as "find a value" but as "find the correct partition" — a fundamental mental model shift that unlocks a whole class of problems.
Why it matters: This problem shows up in FAANG interviews precisely because it tests whether you truly understand binary search at a deep level, not just pattern-matching. The technique generalizes to finding k-th elements, weighted medians, and even some geometry problems.
Part 1: Theory / 理论基础 (5 min)
什么是中位数?/ What Is a Median?
中位数将一个有序序列分成两半:左半部分的所有元素都 ≤ 右半部分的所有元素。
The median divides a sorted sequence into two equal halves where every element on the left ≤ every element on the right.
若总长度为奇数:中位数 = 中间那个元素
若总长度为偶数:中位数 = 中间两个元素的平均值
核心洞见:搜索分割,而非搜索值 / Core Insight: Search for a Partition, Not a Value
给定两个排序数组 nums1 和 nums2,我们要找到一个分割点,使得:
Given two sorted arrays nums1 and nums2, we need to find partitions such that:
nums1: [... L1 | R1 ...]
nums2: [... L2 | R2 ...]
满足以下两个条件:
Meeting both conditions:
左半部分元素数量 = 右半部分元素数量(或相差 1)
Left side has same count as right side (or differs by 1)
L1 ≤ R2 且 L2 ≤ R1(左边所有元素 ≤ 右边所有元素)
L1 ≤ R2 AND L2 ≤ R1 (all left elements ≤ all right elements)
Key insight: we only binary search on the shorter array. Once we fix partition i in nums1, partition j in nums2 is fully determined by the total-half-length constraint:
i + j = half_len = (m + n + 1) // 2
j = half_len - i
所以整个问题变成:在 nums1 的下标范围 [0, m] 上二分,找到满足条件的 i。
So the problem reduces to: binary search over [0, m] in nums1 to find valid i.
Part 2: Step-by-Step Implementation / 一步一步实现 (8 min)
def findMedianSortedArrays(nums1: list[int], nums2: list[int]) -> float:
# Always binary search on the SHORTER array for efficiency# If nums1 is longer, swap them
A, B = nums1, nums2
if len(A) > len(B):
A, B = B, A
m, n = len(A), len(B)
# half_len: number of elements in the "left half" of the merged array# The +1 handles odd total length — left half gets the extra element
half_len = (m + n + 1) // 2# Binary search on partition point i in array A# i = number of elements taken from A for the left half# j = number of elements taken from B for the left half (derived)
lo, hi = 0, m
while lo <= hi:
i = (lo + hi) // 2# partition in A: A[:i] | A[i:]
j = half_len - i # partition in B: B[:j] | B[j:]# Boundary values — use -inf/+inf to handle edge cases# (when partition is at the start or end of an array)
A_left = A[i - 1] if i > 0else float('-inf') # last elem of A's left half
A_right = A[i] if i < m else float('inf') # first elem of A's right half
B_left = B[j - 1] if j > 0else float('-inf') # last elem of B's left half
B_right = B[j] if j < n else float('inf') # first elem of B's right half# Check if we found the correct partition:# All left elements must be ≤ all right elementsif A_left <= B_right and B_left <= A_right:
# FOUND! Compute medianif (m + n) % 2 == 1:
# Odd total: median is the max of both left halvesreturn float(max(A_left, B_left))
else:
# Even total: average of max-left and min-rightreturn (max(A_left, B_left) + min(A_right, B_right)) / 2.0elif A_left > B_right:
# A's left is too big — move partition left in A
hi = i - 1else:
# B_left > A_right: A's left is too small — move partition right in A
lo = i + 1# Should never reach here if inputs are valid sorted arraysraise ValueError("Input arrays are not sorted or otherwise invalid")
# When i=0, there's nothing on A's left — use -inf as sentinel# When i=m, there's nothing on A's right — use +inf as sentinel
A_left = A[i - 1] if i > 0else float('-inf')
A_right = A[i] if i < m else float('inf')
如果不处理边界,你会得到 IndexError。这是最常见的 bug 来源。
If you don't handle boundaries, you get IndexError. This is the #1 bug source.
2. 奇偶性处理 / Odd vs Even Length
half_len = (m + n + 1) // 2# The +1 is critical!# Without +1, for odd total length, left half gets fewer elements# For even: left=right=n/2 elements, median=(max_left+min_right)/2# For odd: left gets one extra, median=max_left
3. 必须在较短数组上二分 / Must binary search the shorter array
if len(A) > len(B):
A, B = B, A
# This ensures j = half_len - i is always valid (0 <= j <= n)# If A is longer, j could go negative!
4. 两个数组都为空 / Edge: empty inputs
# LC guarantees at least one is non-empty, but in real code:ifnot A andnot B: raise ValueError("both empty")
# The -inf/+inf sentinels handle when one array is empty
Part 4: Real-World Application / 实际应用 (2 min)
这个技巧在生产中用在哪里?/ Where does this show up in production?
Monitoring systems aggregate latency histograms from multiple nodes. Finding p50 across sorted arrays from 10 pods is this exact problem.
3. 流媒体中位数 / Streaming median (variant)
LeetCode #295 "Find Median from Data Stream" 用两个堆(max-heap + min-heap)维护中位数——这是对"维护两个有序结构的分割点"这一思想的直接应用。
LC #295 uses two heaps to maintain the partition point dynamically — the same conceptual core.
4. 二分搜索思想的泛化 / Generalizing the "partition binary search" idea
找第 k 小的元素(k-th smallest in two sorted arrays)
找两个序列合并后的任意百分位数
寻找最优分割点(LeetCode #410 Split Array Largest Sum)
The pattern: binary search on a partition/decision variable, not a concrete value — generalizes to split-array problems, capacity optimization, etc.
Part 5: Interview Simulation / 面试模拟 (3 min)
以下是面试官可能追问的 5 个问题和简洁答案:
Q1: 为什么要在较短的数组上二分?/ Why binary search on the shorter array?
因为较短数组长度为 m,二分复杂度是 O(log m)。同时,j = half_len - i 需要满足 0 ≤ j ≤ n,在较短数组上二分可以保证 j 始终有效。如果 m > n,交换两个数组即可。
To get O(log(min(m,n))) and to guarantee j = half_len - i stays in [0, n]. If we search the longer array, j could go out of bounds.
Q2: 如果数组没有排序怎么办?/ What if arrays aren't sorted?
题目保证有序。实际中需要先排序(O(m log m + n log n)),此时不如直接合并找中位数。如果数据流式到来(无法预排序),用两个堆的方案(LC #295)更合适。
The problem guarantees sorted. If not, sort first — but then O((m+n)log(m+n)) merge is simpler. For streaming unsorted data, use the two-heap approach (LC #295).
Q3: 这道题能用递归解吗?/ Can this be solved recursively?
可以。经典递归解法是"找两个有序数组中第 k 小的数",每次递归排除 k/2 个元素,时间复杂度同样是 O(log(m+n))。但迭代二分更直观,代码更简洁,面试推荐迭代版本。
Yes — recursive "find k-th element" approach works: each call eliminates k/2 elements from consideration. Same O(log(m+n)) complexity, but the iterative partition approach is cleaner to code under pressure.
No problem. The comparisons A_left ≤ B_right handle duplicates correctly. Test: [1,1] and [1,1] → median 1.0. Algorithm: max(1,1) = 1.0 ✓.
Q5: 如何扩展到 k 个有序数组?/ How would you extend this to k sorted arrays?
对 k 个数组做二分搜索不再直接适用(搜索空间是 k 维的)。常见方法:
(a) 最小堆合并(O(N log k),N 是总元素数)
(b) 分治:两两合并为一个,递归处理(O(N log k))
(c) 若只要中位数,可以用采样估计(近似算法)
Binary search across k arrays isn't straightforward (k-dimensional search space). Better approaches: (a) min-heap k-way merge O(N log k), (b) divide-and-conquer pairwise merge, (c) sampling-based approximation for very large k.
A = [1 | 3] (i=1: A_left=1, A_right=3)
B = [2 | 4] (j=1: B_left=2, B_right=4)
↑ partition line
Left half: {1, 2} → max = 2
Right half: {3, 4} → min = 3
✅ Diagram matches code exactly. The partition line in the diagram corresponds directly to i=1, j=1 in the code, and the left/right boundary values are the same in both.