Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
Don't merge — binary search a *partition*. Split the combined arrays into a left part and a right part of the right sizes so that everything on the left ≤ everything on the right. Binary search the cut position in the smaller array (the cut in the larger one is then forced), checking the four border elements. When `leftA ≤ rightB` and `leftB ≤ rightA`, the median falls out of those four values. O(log(min(m, n))) time, O(1) space.
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you can reach the O(log(min(m,n))) partition method (or at least the O(log(m+n)) k-th element method) and handle the brutal edge cases — empty sides, odd/even totals, equal borders — without bugs.
Where candidates slip
Binary searching the larger array (wrong complexity), mishandling the empty-partition borders (index out of bounds), or botching the odd/even median formula.
How to stand out
State the merge baseline and its O(m+n), then pivot to 'binary search the cut', explain the ±∞ sentinel trick that kills all the edge cases, and derive j from i so the left half size is fixed.
Choose
Compare the available approaches
Use constraints and trade-offs to select the route you can defend in an interview.
Interactive decision treeInteractiveChoose the right approachFirst decision previewcut A at i, derive cut B at j = half - iAleft <= Bright AND Bleft <= Aright?YesAleft > BrightExplore the full treeCollapse the tree
Learn & trace
Build each solution step by step
Move from the core idea to a visual trace, implementation, proof, and edge cases.
Approach 1 of 2
Merge (or Half-Merge) with Two Pointers — Baseline
1Hint 1Explore hintHide hint
If you merged the two sorted arrays, where would the median sit?
2Hint 2Explore hintHide hint
You don't need the full merge — just advance two pointers until you've passed (m+n)/2 elements, tracking the middle one or two.
3Hint 3Explore hintHide hint
It's O(m+n) and trivially correct. Use it to sanity-check, but the prompt wants O(log(m+n)).
A · Core idea
Step two pointers through nums1 and nums2, always taking the smaller current element, until you've consumed (m + n) / 2 + 1 elements; remember the last one or two to form the median.
Why mention it. It's the obviously-correct reference and a clean way to define what the median is, which helps you reason about the faster method. Why it's not the final answer. It's O(m + n). The prompt explicitly asks for O(log(m + n)), so we have to avoid touching every element.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
nums1 = [1, 3], nums2 = [2]take min(1,2)=1
count=1, advance nums1
last = 12.0C · Code with teaching comments
Reference implementation previewpublic double findMedianSortedArrays(int[] a, int[] b) { int m = a.length, n = b.length, total = m + n; int i = 0, j = 0; int prev = 0, curr = 0; for (int count = 0; count <= total / 2; count++) {Explore the full codeHide the full code
D · Why it works and complexityO(m + n) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
The merge baseline reveals the goal precisely: we only care about the one or two elements at the centre, not the whole merge. That observation — 'we just need the right position, not the full order' — is what motivates binary searching a partition.
ComplexityO(m + n) time, O(1) space — Walk both arrays once with two pointers, stopping at the middle — linear in the total length, constant memory.
E · Edge cases and pitfalls3O(m+n) — fails the asymptotic requirement even though it passes the tests.Explore edge casesHide edge cases
Pitfalls
- O(m+n) — fails the asymptotic requirement even though it passes the tests.
- Off-by-one on how many elements to consume for odd vs even totals.
- Forgetting the j >= n / i < m guards when one array runs out.
Approach 2 of 2 · Optimal
Binary Search the Partition (Optimal)
1Hint 1Explore hintHide hint
Imagine drawing one vertical cut through each array so that the combined left side has exactly half the elements. What must be true about the four values touching the cut for it to be the median split?
2Hint 2Explore hintHide hint
Fix the total left-size to (m+n+1)/2. Then the cut position j in B is forced once you choose the cut i in A — so you only search i.
3Hint 3Explore hintHide hint
Search i in the SMALLER array. A cut is valid when Aleft ≤ Bright and Bleft ≤ Aright. If Aleft > Bright, your A-cut is too far right; otherwise too far left. Use ±∞ for out-of-range borders.
A · Core idea
Find, without merging, a partition that places exactly the lower half of all elements on the left.
Reframe the median as a cut. A median splits the m + n values into a left part and a right part where (a) the left part has a fixed size and (b) every left value ≤ every right value. If we cut nums1 after index i (so i elements of A go left) and nums2 after index j (so j elements of B go left), then the left part has i + j elements. We want the left part to hold half = (m + n + 1) / 2 elements (the +1 puts the extra element on the left for odd totals), so once we pick i, the cut j = half - i is forced. That reduces a two-dimensional search to a one-dimensional binary search over i.
Search the smaller array. We binary search i in [0, m] after swapping so that A is the shorter array. This bounds the work at O(log(min(m, n))) and keeps j = half - i within [0, n] (guaranteed when m <= n).
The four border values. Around the cut sit Aleft = A[i-1], Aright = A[i], Bleft = B[j-1], Bright = B[j]. When a cut lands at the very start (i == 0) there is no left element, so we treat Aleft = -∞; at the end (i == m) there is no right element, so Aright = +∞; likewise for B. These sentinels are the trick that erases every empty-partition edge case — no special branches for empty arrays or cuts at the boundary.
The validity condition. Because each array is individually sorted, Aleft <= Aright and Bleft <= Bright automatically. The cut is the correct global split exactly when the cross conditions also hold: Aleft <= Bright and Bleft <= Aright. That means every element on the left (the max of which is max(Aleft, Bleft)) is ≤ every element on the right (the min of which is min(Aright, Bright)).
Driving the search. If Aleft > Bright, we took too many large elements from A into the left — move the A-cut left: hi = i - 1. If instead Bleft > Aright (the only other failure), the A-cut is too far left — move it right: lo = i + 1. Otherwise we've found the cut.
Reading off the median. With a valid cut: if m + n is odd, the left side has the extra element, so the median is max(Aleft, Bleft). If even, it's the average of the two central values: (max(Aleft, Bleft) + min(Aright, Bright)) / 2. The (m + n + 1) / 2 choice of half is what makes the odd case this clean.
Why it terminates correctly. The window [lo, hi] on i strictly shrinks each iteration, and a valid partition always exists, so the loop returns from inside on the correct cut.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
nums1 = [1, 3], nums2 = [2] (A is the shorter, m=1 after swap → A=[2], B=[1,3])Array state
i=0, j=2
Aleft=-∞, Aright=2, Bleft=3, Bright=+∞. Bleft(3) > Aright(2) → move A-cut right
2.0C · Code with teaching comments
D · Why it works and complexityO(log(min(m, n))) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
The reframing — from 'merge and index' to 'find the balancing cut' — is the transferable idea. Deriving one cut from the other collapses the search to one dimension, and the ±∞ sentinels turn a notoriously edge-case-heavy problem into a handful of clean comparisons. The same partition-search mindset solves the generalised 'k-th element of two sorted arrays' and median-of-streams variants.
ComplexityO(log(min(m, n))) time, O(1) space — Binary search over the cut position in the smaller array (length min(m, n)) → log₂(min(m, n)) iterations, O(1) work each. No extra memory beyond a few variables.
E · Edge cases and pitfalls8nums1 = [], nums2 = [1] — m=0 → only i=0 possible; Aleft=-∞, Aright=+∞; median reads from B's borders → 1.0.Explore edge casesHide edge cases
Edge cases handled
nums1 = [], nums2 = [1]m=0 → only i=0 possible; Aleft=-∞, Aright=+∞; median reads from B's borders → 1.0.nums1 = [1, 2], nums2 = [3, 4]Cut puts {1,2} | {3,4}; even total → (max(2,-∞... actually 2) + min(3,...)) → (2+3)/2 = 2.5.nums1 = [3], nums2 = [-2, -1]After swap A=[3] is longer? n≥m enforced; sentinels handle all-negative values correctly.all of A less than all of BCut lands at i=m or i=0 and sentinels make the cross conditions pass on the first valid position.
Pitfalls
- Binary searching the larger array — gives O(log(max(m,n))) and can push j out of range.
- Forgetting ±∞ sentinels — index-out-of-bounds on cuts at the boundary or empty arrays.
- Using (m+n)/2 instead of (m+n+1)/2 for half — breaks the clean odd-median formula.
- Integer division on the even-case average — must divide by 2.0 to keep the fractional median.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic double findMedianSortedArrays(int[] nums1, int[] nums2) { if (nums1.length > nums2.length) { return findMedianSortedArrays(nums2, nums1); } int m = nums1.length, n = nums2.length;Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
1Searching the longer array
Binary searching the larger array makes complexity O(log(max(m,n))) and lets the derived cut j = half - i fall outside [0, n], causing wrong borders or crashes. Always swap so the searched array is the shorter one.
Explore the code comparisonHide the code comparison
Searching the longer array
Binary searching the larger array makes complexity O(log(max(m,n))) and lets the derived cut j = half - i fall outside [0, n], causing wrong borders or crashes. Always swap so the searched array is the shorter one.
Don't write this
m, n = len(nums1), len(nums2)
# no swap — searches nums1 even if it is the longer array
half = (m + n + 1) // 2
lo, hi = 0, mWrite this instead
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1
m, n = len(nums1), len(nums2)
half = (m + n + 1) // 2
lo, hi = 0, m2Missing boundary sentinels
When a cut sits at index 0 or the array end, the missing border element must act as ±∞. Reading nums[i] or nums[i-1] directly throws an index error and breaks empty-array inputs.
Explore the code comparisonHide the code comparison
Missing boundary sentinels
When a cut sits at index 0 or the array end, the missing border element must act as ±∞. Reading nums[i] or nums[i-1] directly throws an index error and breaks empty-array inputs.
Don't write this
int aLeft = nums1[i - 1]; // crashes when i == 0
int aRight = nums1[i]; // crashes when i == mWrite this instead
int aLeft = (i == 0) ? Integer.MIN_VALUE : nums1[i - 1];
int aRight = (i == m) ? Integer.MAX_VALUE : nums1[i];3Integer division in the even case
The median of an even-length total is generally a non-integer (e.g. 2.5). Dividing the sum of the two middle values by an integer 2 truncates the fraction.
Explore the code comparisonHide the code comparison
Integer division in the even case
The median of an even-length total is generally a non-integer (e.g. 2.5). Dividing the sum of the two middle values by an integer 2 truncates the fraction.
Don't write this
return (Math.max(aLeft, bLeft) + Math.min(aRight, bRight)) / 2;Write this instead
return (Math.max(aLeft, bLeft) + Math.min(aRight, bRight)) / 2.0;Revise
Carry the pattern into the interview
Pattern to remember
Binary search the partition of the smaller array
Code pattern to memorize
ensure A is the shorter array
half = (m + n + 1) // 2
lo, hi = 0, m
while lo <= hi:
i = (lo + hi) // 2 # cut in A
j = half - i # cut in B
Aleft = A[i-1] if i>0 else -inf; Aright = A[i] if i<m else +inf
Bleft = B[j-1] if j>0 else -inf; Bright = B[j] if j<n else +inf
if Aleft <= Bright and Bleft <= Aright: # correct cut
if (m+n) odd: return max(Aleft, Bleft)
return (max(Aleft,Bleft) + min(Aright,Bright)) / 2
elif Aleft > Bright: hi = i - 1
else: lo = i + 1Rules to remember
- 1Always binary search the smaller array so the range is
[0, min(m, n)]→O(log(min(m, n))). - 2The cut in B is derived:
j = (m + n + 1) // 2 − i, so the left side always holds exactly half the elements. - 3Guard the borders with
±∞when a cut sits at index 0 or the array end — this removes every empty-side special case. - 4Correct partition condition is
Aleft ≤ Bright AND Bleft ≤ Aright; ifAleft > Brightmove the A-cut left, else move it right. - 5Use
(m + n + 1) // 2so the left side has the extra element on odd total — then the odd-median ismax(Aleft, Bleft)with no extra arithmetic.
Use this pattern when
- Median / k-th element across two (or more) sorted arrays in sub-linear time
- Strict `O(log(m+n))` requirement that rules out merging
- Any 'find the split that balances two sorted sequences' framing
Choose another pattern when
- O(m + n) is acceptable → just merge with two pointers; far less error-prone
- Arrays are unsorted → sort or use selection; binary-search partition needs sorted input
- You need the full merged array, not just the median → merging is unavoidable
Interview takeaway
The leap is to stop thinking 'merge then index' and start thinking 'where do I cut?'. Binary searching a partition — with ±∞ sentinels erasing the edge cases — is the canonical O(log) technique for order-statistics across sorted inputs.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternBinary search a partition for order statistics across sorted arrays. Recognise it when you need the median / k-th value of two sorted sequences in logarithmic time: derive one cut from the other, use ±∞ sentinels, and check the four border values. Generalises to the k-th element of two sorted arrays.
Practice queueDirect variations and pattern siblings
Direct follow-ups
- Kth Largest Element in an ArrayComing soonOrder statistics on one array — quickselect averages O(n).
- Kth Element of Two Sorted Arrays (generalisation)Coming soonSame partition idea but solve for an arbitrary k, discarding k/2 elements per step.
- Find Median from Data StreamComing soonStreaming median with two heaps instead of static sorted arrays.
- Binary SearchThe base template; this problem binary searches a cut rather than an element.