Median of Two Sorted Arrays (LC 4)
You're given two already-sorted arrays, nums1 (size m) and nums2 (size n). Without necessarily merging them, work out the median value of all m + n numbers combined.
Target an overall running time of O(log(m + n)).
Worked Examples
nums1 = [1,3], nums2 = [2]2.00000nums1 = [1,2], nums2 = [3,4]2.50000⚖️Formal Constraints & Bounds
nums1.length == mnums2.length == n0 <= m <= 10000 <= n <= 10001 <= m + n <= 2000-106 <= nums1[i], nums2[i] <= 106
Core Insight
Search how many values to take from the shorter list, not a value. The left side of a cut that takes i values from one list and k - i from the other holds exactly k values. 'Is right1 at least left2?' is False and then True as i grows, so Lower Bound finds the cut. Use inf and -inf for a missing value at an edge.
Real-World Scenario & Production Applications
Merging pre-sorted result shards from two distributed database partitions to compute a percentile without materializing the full merged dataset.
Subproblems & Recurrence Decomposition3 Phases
A cut takes i values from the shorter list and k - i values from the other list, so the left side holds exactly k values. Swap the lists so that nums1 is the shorter one. The candidates are the numbers of values taken from nums1, from max(0, k - n) to min(m, k).
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1
m, n = len(nums1), len(nums2)
lo = max(0, k - n)
hi = min(m, k) + 1Step-by-Step Execution Trace Table
| Step | Range [lo, hi) | i | right1 | left2 | right1 >= left2 | Decision | New range |
|---|---|---|---|---|---|---|---|
| Setup | nums1 = [1, 2], nums2 = [3, 4]. The total is 4, so the median needs the 2nd and the 3rd smallest values: two calls. | ||||||
| 1 | [0, 3) (k = 2) | 1 | nums1[1] = 2 | nums2[0] = 3 | False | lo = mid + 1 | [2, 3) |
| 2 | [2, 3) (k = 2) | 2 | inf (no nums1[2]) | -inf (nothing taken from nums2) | True | hi = mid | [2, 2) |
The range is empty. The cut is 2, so max(left1, left2) = max(2, -inf) = 2. | |||||||
| 3 | [1, 3) (k = 3) | 2 | inf | nums2[0] = 3 | True | hi = mid | [1, 2) |
| 4 | [1, 2) (k = 3) | 1 | nums1[1] = 2 | nums2[1] = 4 | False | lo = mid + 1 | [2, 2) |
The range is empty. The cut is 2, so max(left1, left2) = max(2, 3) = 3. The median is (2 + 3) / 2 = 2.5. |
At the edge of a list, the missing value is float('inf') or float('-inf'). Without it, step 2 would read nums1[2] and raise IndexError.
The Math, Step by Step
1. The cut the search looks for
Imagine all values merged into one sorted list. The code never merges. It takes the first values of the shorter list nums1 and the first values of the other list nums2. These values are the left side. The remaining values are the right side.
The left side holds exactly values for every , so the search only chooses , and follows from it.
The -th smallest value of both lists is the largest value on the left side, when the cut is right. The median is the -th smallest value for . When is even, it is the mean of the -th and the -th smallest values.
2. Checking one cut
Four values sit next to the two cuts:
| Name | Value | Meaning |
|---|---|---|
left1 | nums1[i - 1], or when | the largest value of nums1 on the left side |
right1 | nums1[i], or when | the smallest value of nums1 on the right side |
left2 | nums2[k - i - 1], or when | the largest value of nums2 on the left side |
right2 | nums2[k - i], or when | the smallest value of nums2 on the right side |
Each list is sorted, so left1 <= right1 and left2 <= right2 always hold. The cut is right when every left value is at most every right value. That needs only two cross checks: left1 <= right2 and left2 <= right1.
3. Why one question is enough
Move one step to the right. right1 can only grow, because nums1 is sorted. left2 can only shrink, because gets smaller. So the answer to "is right1 >= left2?" is False for small and True from some on.
The first where it is True is the right cut. The answer one step before it was False, so nums1[i - 1] < nums2[k - i], which is left1 < right2. Both cross checks hold.
So Lower Bound over , with the check right1 >= left2, finds the right cut. There is no second branch and no half.
4. The range and the sentinels
lo = max(0, k - n): when is larger than , at least values must come from nums1.
hi = min(m, k) + 1: nums1 has values and the left side has values, so is at most . The + 1 makes hi one past the last candidate.
The values and are sentinels: stand-in values for a missing value at an edge. When , there is no nums1[i], and right1 is . When , no value is taken from nums2, and left2 is . The last candidate always passes the check, so the search always finds a cut.
The code swaps the lists so that nums1 is the shorter list. The search then takes rounds.
5. Example 1 by hand
nums1 = [1,3], nums2 = [2]. The total is 3, so and one call is enough. The first list is longer, so the code swaps them: nums1 = [2], nums2 = [1,3], with and . Then lo = max(0, 2 - 2) = 0 and hi = min(1, 2) + 1 = 2.
lo | hi | right1 | left2 | right1 >= left2 | New range | |
|---|---|---|---|---|---|---|
| 0 | 2 | 1 | (no nums1[1]) | nums2[0] = 1 | True | hi = 1 |
| 0 | 1 | 0 | nums1[0] = 2 | nums2[1] = 3 | False | lo = 1 |
The range [1, 1) is empty, so the cut is : one value from nums1 and one from nums2. left1 = 2 and left2 = 1, so the 2nd smallest value is . The code returns 2.0, the expected output 2.00000.
6. Example 2 by hand
nums1 = [1,2], nums2 = [3,4]. The total is 4, so , and the median needs the 2nd and the 3rd smallest values: two calls.
For : lo = max(0, 2 - 2) = 0, hi = min(2, 2) + 1 = 3.
lo | hi | right1 | left2 | right1 >= left2 | New range | |
|---|---|---|---|---|---|---|
| 0 | 3 | 1 | nums1[1] = 2 | nums2[0] = 3 | False | lo = 2 |
| 2 | 3 | 2 | (nothing taken from nums2) | True | hi = 2 |
The cut is : left1 = 2 and left2 = -inf, so the 2nd smallest value is 2.
For : lo = max(0, 3 - 2) = 1, hi = min(2, 3) + 1 = 3. The search finds the cut , so left1 = 2 and left2 = nums2[0] = 3, and the 3rd smallest value is 3.
The median is . The code returns 2.5, the expected output 2.50000.
7. From the math to the code
| Math | In findMedianSortedArrays and kth_smallest_of_two |
|---|---|
| search the shorter list | if len(nums1) > len(nums2): then swap |
k = (total + 1) // 2 | |
| from to | lo = max(0, k - n) and hi = min(m, k) + 1 |
the question "is right1 >= left2?" | def right1_at_least_left2(i) |
| the sentinels | float('-inf') and float('inf') |
| find the first True | i = binary_search_lower_bound(lo, hi, right1_at_least_left2) |
| the -th smallest value | return max(left1, left2) |
| the median | one call for an odd total, two calls for an even total |
| 1 | if len(nums1) > len(nums2): |
| 2 | nums1, nums2 = nums2, nums1 |
| 3 | m, n = len(nums1), len(nums2) |
| 4 | def right1_at_least_left2(i: int) -> bool: |
| 5 | return right1 >= left2 |
| 6 | lo = max(0, k - n) |
| 7 | hi = min(m, k) + 1 |
| 8 | i = binary_search_lower_bound(lo, hi, right1_at_least_left2) |
| 9 | return max(left1, left2) |
Conceptual Narrative
🧭 Conceptual Foundation: Searching for a Cut, Not a Value
The key idea of LC 4 is that we do not search for a value. We search for how many values to take from the shorter list. That count is a position, so Lower Bound runs over positions, not over values.
1. One cut, one forced cut
We want the -th smallest of two sorted lists. A cut takes values from the shorter list and values from the other list. The left side always holds exactly values. So choosing forces the other cut.
The cut is right when every left value is at most every right value. The largest left value is then the -th smallest.
2. One question
Four values sit next to the cut: left1, right1, left2 and right2. Each list is sorted, so only two pairs cross the cut. One question covers both: is right1 at least left2?
When grows, right1 only grows and left2 only shrinks. So the answers are False and then True, and Lower Bound finds the first True. This is the same shape as every other card in this pattern: a check, a range and one call.
3. The edges
At the edge of a list, one value is missing. When , there is no nums1[i]. When , no value is taken from nums2. We write float('inf') and float('-inf') for the missing values. The trap is to read the missing value anyway: Python raises IndexError.
4. From k to the median
For an odd total, the median is the -th smallest for . For an even total, it is the mean of the -th and the -th smallest values, so the code calls the helper twice.
Next step: for three or more sorted lists, or a sorted matrix, one cut no longer decides the others. Those problems use the Kth Smallest card, which searches the values and counts.
Reading past the end of a list without
float('inf')Starting
loat 0 instead ofmax(0, k - n)Reading
nums2[k - i]instead ofnums2[k - i - 1]Making one call when the total is even
Averaging with
//instead of/
4-Phase Thought Process Model
Pattern Recognition Signals
The 10-second spot
Two sorted lists, and the median or a k-th value in less than linear time. A merge would read every value. The answer is a count of values to take from one list, so Lower Bound runs over counts.
Formulating the Predicate & Invariants
Turning intuition into a boolean rule
Invariant: a cut that takes i values from the shorter list and k - i values from the other puts exactly k values on the left. Every cut before lo has right1 smaller than left2, and the cut at hi passes. The check right1 >= left2 is False and then True as i grows.
Silent Failure Traps & Edge Cases
Where confident candidates still lose points
Reading past the end of a list: when i == m there is no nums1[i], and when k - i == 0 no value is taken from nums2. Without float('inf') and float('-inf'), kth_smallest_of_two([1, 3], [2, 4], 4) raises IndexError.
Starting lo at 0: when k is larger than n, i = 0 makes k - i larger than n, and nums2[k - i - 1] is past the end. Start at max(0, k - n).
Making one call for an even total: [1, 2] and [3, 4] need the 2nd and the 3rd smallest values. One call gives 2.0, and the median is 2.5.
The 60-Second Interview Pitch
Say this out loud before you type a single line
"This is a Lower Bound search over a count. A cut takes i values from the shorter list and k - i from the other, so the left side holds exactly k values. I ask one question for each i: is right1 at least left2? right1 only grows and left2 only shrinks as i grows, so the answers are False and then True, and Lower Bound finds the first True. The range is max(0, k - n) to min(m, k) + 1. The largest left value is the k-th smallest. For an odd total I make one call, and for an even total I make two calls and take the mean. The trap is reading past the end of a list: I use inf and -inf for a missing value. That is O(log min(M, N)) time and
O(1)space."
Complexity & Mathematical Proof
O(log(min(M, N)))
Look at the structure: Lower Bound runs while lo < hi: over the cuts [max(0, k - n), min(m, k) + 1) of the shorter list, at most min(M, N) + 1 candidates. Each pass halves the range. Each pass calls right1_at_least_left2(mid), which reads two values. The median makes at most two calls. So the time is O(log min(M, N)).
O(1)
Look at the memory used: Lower Bound and the check are iterative, so the call stack holds a few frames. Only a few integers and four boundary values exist at once. No merged list is built. Auxiliary space is O(1).
Derivation Progression
search space = [0, min(M, N)]
Binary searching the shorter array bounds the search range to min(M, N) + 1 candidates.
j = half - i
The partition index in the longer array is derived arithmetically, not searched, costing O(1) per iteration.
⌊ log2(min(M, N) + 1) ⌋ + 1 iterations
Each iteration halves the min(M, N) + 1 candidate cuts, so the loop finds the correct cut within at most ⌊ log2(min(M, N) + 1) ⌋ + 1 iterations.
Variable Definitions
Length of the first sorted array
Length of the second sorted array
Memory Architecture & Bounds
O(1) Iterative while loop with zero recursion frames
O(1) Only scalar boundary values in CPU registers
O(1) Returns a single floating-point median
Boundary Best / Worst Cases
when one array is empty and the other's length determines the median directly.
.
for two comparably-sized arrays.
Recurrence Tree Topology
Senior SWE Deconstruction & Hardware Caveats
The statement gives "two already-sorted arrays" and asks us to "work out the median" in O(log(m + n)) time. That bound is the giveaway: we cannot merge the arrays (). The answer is a count of values to take from the shorter array, so Lower Bound runs over counts: , better than asked.
Array sizes are , and the cost depends only on the shorter array: nums1 has cuts, so the search runs at most passes, 10 at LeetCode's limit, however long nums2 is. The range of cuts is [max(0, k - n), min(m, k) + 1).
The card's traps are reading past the end of a list (use float('inf') and float('-inf')), starting lo at 0, and making one call for an even total. At scale there is one more: in a language with fixed-width integers, lower_middle + upper_middle can overflow before it is halved when the values are near the type's limit; halve in floating point or compute lower_middle + (upper_middle - lower_middle) / 2.
Median of Two Sorted Arrays (LC 4)
You're given two already-sorted arrays, nums1 (size m) and nums2 (size n). Without necessarily merging them, work out the median value of all m + n numbers combined.
Target an overall running time of O(log(m + n)).
Worked Examples
nums1 = [1,3], nums2 = [2]2.00000nums1 = [1,2], nums2 = [3,4]2.50000⚖️Formal Constraints & Bounds
nums1.length == mnums2.length == n0 <= m <= 10000 <= n <= 10001 <= m + n <= 2000-106 <= nums1[i], nums2[i] <= 106
Core Insight
Search how many values to take from the shorter list, not a value. The left side of a cut that takes i values from one list and k - i from the other holds exactly k values. 'Is right1 at least left2?' is False and then True as i grows, so Lower Bound finds the cut. Use inf and -inf for a missing value at an edge.
Real-World Scenario & Production Applications
Merging pre-sorted result shards from two distributed database partitions to compute a percentile without materializing the full merged dataset.
Subproblems & Recurrence Decomposition3 Phases
A cut takes i values from the shorter list and k - i values from the other list, so the left side holds exactly k values. Swap the lists so that nums1 is the shorter one. The candidates are the numbers of values taken from nums1, from max(0, k - n) to min(m, k).
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1
m, n = len(nums1), len(nums2)
lo = max(0, k - n)
hi = min(m, k) + 1Step-by-Step Execution Trace Table
| Step | Range [lo, hi) | i | right1 | left2 | right1 >= left2 | Decision | New range |
|---|---|---|---|---|---|---|---|
| Setup | nums1 = [1, 2], nums2 = [3, 4]. The total is 4, so the median needs the 2nd and the 3rd smallest values: two calls. | ||||||
| 1 | [0, 3) (k = 2) | 1 | nums1[1] = 2 | nums2[0] = 3 | False | lo = mid + 1 | [2, 3) |
| 2 | [2, 3) (k = 2) | 2 | inf (no nums1[2]) | -inf (nothing taken from nums2) | True | hi = mid | [2, 2) |
The range is empty. The cut is 2, so max(left1, left2) = max(2, -inf) = 2. | |||||||
| 3 | [1, 3) (k = 3) | 2 | inf | nums2[0] = 3 | True | hi = mid | [1, 2) |
| 4 | [1, 2) (k = 3) | 1 | nums1[1] = 2 | nums2[1] = 4 | False | lo = mid + 1 | [2, 2) |
The range is empty. The cut is 2, so max(left1, left2) = max(2, 3) = 3. The median is (2 + 3) / 2 = 2.5. |
At the edge of a list, the missing value is float('inf') or float('-inf'). Without it, step 2 would read nums1[2] and raise IndexError.
The Math, Step by Step
1. The cut the search looks for
Imagine all values merged into one sorted list. The code never merges. It takes the first values of the shorter list nums1 and the first values of the other list nums2. These values are the left side. The remaining values are the right side.
The left side holds exactly values for every , so the search only chooses , and follows from it.
The -th smallest value of both lists is the largest value on the left side, when the cut is right. The median is the -th smallest value for . When is even, it is the mean of the -th and the -th smallest values.
2. Checking one cut
Four values sit next to the two cuts:
| Name | Value | Meaning |
|---|---|---|
left1 | nums1[i - 1], or when | the largest value of nums1 on the left side |
right1 | nums1[i], or when | the smallest value of nums1 on the right side |
left2 | nums2[k - i - 1], or when | the largest value of nums2 on the left side |
right2 | nums2[k - i], or when | the smallest value of nums2 on the right side |
Each list is sorted, so left1 <= right1 and left2 <= right2 always hold. The cut is right when every left value is at most every right value. That needs only two cross checks: left1 <= right2 and left2 <= right1.
3. Why one question is enough
Move one step to the right. right1 can only grow, because nums1 is sorted. left2 can only shrink, because gets smaller. So the answer to "is right1 >= left2?" is False for small and True from some on.
The first where it is True is the right cut. The answer one step before it was False, so nums1[i - 1] < nums2[k - i], which is left1 < right2. Both cross checks hold.
So Lower Bound over , with the check right1 >= left2, finds the right cut. There is no second branch and no half.
4. The range and the sentinels
lo = max(0, k - n): when is larger than , at least values must come from nums1.
hi = min(m, k) + 1: nums1 has values and the left side has values, so is at most . The + 1 makes hi one past the last candidate.
The values and are sentinels: stand-in values for a missing value at an edge. When , there is no nums1[i], and right1 is . When , no value is taken from nums2, and left2 is . The last candidate always passes the check, so the search always finds a cut.
The code swaps the lists so that nums1 is the shorter list. The search then takes rounds.
5. Example 1 by hand
nums1 = [1,3], nums2 = [2]. The total is 3, so and one call is enough. The first list is longer, so the code swaps them: nums1 = [2], nums2 = [1,3], with and . Then lo = max(0, 2 - 2) = 0 and hi = min(1, 2) + 1 = 2.
lo | hi | right1 | left2 | right1 >= left2 | New range | |
|---|---|---|---|---|---|---|
| 0 | 2 | 1 | (no nums1[1]) | nums2[0] = 1 | True | hi = 1 |
| 0 | 1 | 0 | nums1[0] = 2 | nums2[1] = 3 | False | lo = 1 |
The range [1, 1) is empty, so the cut is : one value from nums1 and one from nums2. left1 = 2 and left2 = 1, so the 2nd smallest value is . The code returns 2.0, the expected output 2.00000.
6. Example 2 by hand
nums1 = [1,2], nums2 = [3,4]. The total is 4, so , and the median needs the 2nd and the 3rd smallest values: two calls.
For : lo = max(0, 2 - 2) = 0, hi = min(2, 2) + 1 = 3.
lo | hi | right1 | left2 | right1 >= left2 | New range | |
|---|---|---|---|---|---|---|
| 0 | 3 | 1 | nums1[1] = 2 | nums2[0] = 3 | False | lo = 2 |
| 2 | 3 | 2 | (nothing taken from nums2) | True | hi = 2 |
The cut is : left1 = 2 and left2 = -inf, so the 2nd smallest value is 2.
For : lo = max(0, 3 - 2) = 1, hi = min(2, 3) + 1 = 3. The search finds the cut , so left1 = 2 and left2 = nums2[0] = 3, and the 3rd smallest value is 3.
The median is . The code returns 2.5, the expected output 2.50000.
7. From the math to the code
| Math | In findMedianSortedArrays and kth_smallest_of_two |
|---|---|
| search the shorter list | if len(nums1) > len(nums2): then swap |
k = (total + 1) // 2 | |
| from to | lo = max(0, k - n) and hi = min(m, k) + 1 |
the question "is right1 >= left2?" | def right1_at_least_left2(i) |
| the sentinels | float('-inf') and float('inf') |
| find the first True | i = binary_search_lower_bound(lo, hi, right1_at_least_left2) |
| the -th smallest value | return max(left1, left2) |
| the median | one call for an odd total, two calls for an even total |
| 1 | if len(nums1) > len(nums2): |
| 2 | nums1, nums2 = nums2, nums1 |
| 3 | m, n = len(nums1), len(nums2) |
| 4 | def right1_at_least_left2(i: int) -> bool: |
| 5 | return right1 >= left2 |
| 6 | lo = max(0, k - n) |
| 7 | hi = min(m, k) + 1 |
| 8 | i = binary_search_lower_bound(lo, hi, right1_at_least_left2) |
| 9 | return max(left1, left2) |
Conceptual Narrative
🧭 Conceptual Foundation: Searching for a Cut, Not a Value
The key idea of LC 4 is that we do not search for a value. We search for how many values to take from the shorter list. That count is a position, so Lower Bound runs over positions, not over values.
1. One cut, one forced cut
We want the -th smallest of two sorted lists. A cut takes values from the shorter list and values from the other list. The left side always holds exactly values. So choosing forces the other cut.
The cut is right when every left value is at most every right value. The largest left value is then the -th smallest.
2. One question
Four values sit next to the cut: left1, right1, left2 and right2. Each list is sorted, so only two pairs cross the cut. One question covers both: is right1 at least left2?
When grows, right1 only grows and left2 only shrinks. So the answers are False and then True, and Lower Bound finds the first True. This is the same shape as every other card in this pattern: a check, a range and one call.
3. The edges
At the edge of a list, one value is missing. When , there is no nums1[i]. When , no value is taken from nums2. We write float('inf') and float('-inf') for the missing values. The trap is to read the missing value anyway: Python raises IndexError.
4. From k to the median
For an odd total, the median is the -th smallest for . For an even total, it is the mean of the -th and the -th smallest values, so the code calls the helper twice.
Next step: for three or more sorted lists, or a sorted matrix, one cut no longer decides the others. Those problems use the Kth Smallest card, which searches the values and counts.
Reading past the end of a list without
float('inf')Starting
loat 0 instead ofmax(0, k - n)Reading
nums2[k - i]instead ofnums2[k - i - 1]Making one call when the total is even
Averaging with
//instead of/
4-Phase Thought Process Model
Pattern Recognition Signals
The 10-second spot
Two sorted lists, and the median or a k-th value in less than linear time. A merge would read every value. The answer is a count of values to take from one list, so Lower Bound runs over counts.
Formulating the Predicate & Invariants
Turning intuition into a boolean rule
Invariant: a cut that takes i values from the shorter list and k - i values from the other puts exactly k values on the left. Every cut before lo has right1 smaller than left2, and the cut at hi passes. The check right1 >= left2 is False and then True as i grows.
Silent Failure Traps & Edge Cases
Where confident candidates still lose points
Reading past the end of a list: when i == m there is no nums1[i], and when k - i == 0 no value is taken from nums2. Without float('inf') and float('-inf'), kth_smallest_of_two([1, 3], [2, 4], 4) raises IndexError.
Starting lo at 0: when k is larger than n, i = 0 makes k - i larger than n, and nums2[k - i - 1] is past the end. Start at max(0, k - n).
Making one call for an even total: [1, 2] and [3, 4] need the 2nd and the 3rd smallest values. One call gives 2.0, and the median is 2.5.
The 60-Second Interview Pitch
Say this out loud before you type a single line
"This is a Lower Bound search over a count. A cut takes i values from the shorter list and k - i from the other, so the left side holds exactly k values. I ask one question for each i: is right1 at least left2? right1 only grows and left2 only shrinks as i grows, so the answers are False and then True, and Lower Bound finds the first True. The range is max(0, k - n) to min(m, k) + 1. The largest left value is the k-th smallest. For an odd total I make one call, and for an even total I make two calls and take the mean. The trap is reading past the end of a list: I use inf and -inf for a missing value. That is O(log min(M, N)) time and
O(1)space."
Complexity & Mathematical Proof
O(log(min(M, N)))
Look at the structure: Lower Bound runs while lo < hi: over the cuts [max(0, k - n), min(m, k) + 1) of the shorter list, at most min(M, N) + 1 candidates. Each pass halves the range. Each pass calls right1_at_least_left2(mid), which reads two values. The median makes at most two calls. So the time is O(log min(M, N)).
O(1)
Look at the memory used: Lower Bound and the check are iterative, so the call stack holds a few frames. Only a few integers and four boundary values exist at once. No merged list is built. Auxiliary space is O(1).
Derivation Progression
search space = [0, min(M, N)]
Binary searching the shorter array bounds the search range to min(M, N) + 1 candidates.
j = half - i
The partition index in the longer array is derived arithmetically, not searched, costing O(1) per iteration.
⌊ log2(min(M, N) + 1) ⌋ + 1 iterations
Each iteration halves the min(M, N) + 1 candidate cuts, so the loop finds the correct cut within at most ⌊ log2(min(M, N) + 1) ⌋ + 1 iterations.
Variable Definitions
Length of the first sorted array
Length of the second sorted array
Memory Architecture & Bounds
O(1) Iterative while loop with zero recursion frames
O(1) Only scalar boundary values in CPU registers
O(1) Returns a single floating-point median
Boundary Best / Worst Cases
when one array is empty and the other's length determines the median directly.
.
for two comparably-sized arrays.
Recurrence Tree Topology
Senior SWE Deconstruction & Hardware Caveats
The statement gives "two already-sorted arrays" and asks us to "work out the median" in O(log(m + n)) time. That bound is the giveaway: we cannot merge the arrays (). The answer is a count of values to take from the shorter array, so Lower Bound runs over counts: , better than asked.
Array sizes are , and the cost depends only on the shorter array: nums1 has cuts, so the search runs at most passes, 10 at LeetCode's limit, however long nums2 is. The range of cuts is [max(0, k - n), min(m, k) + 1).
The card's traps are reading past the end of a list (use float('inf') and float('-inf')), starting lo at 0, and making one call for an even total. At scale there is one more: in a language with fixed-width integers, lower_middle + upper_middle can overflow before it is halved when the values are near the type's limit; halve in floating point or compute lower_middle + (upper_middle - lower_middle) / 2.