The boundary initialization—low = max(0, k - n) and high = min(k, m)—is usually the trickiest part of this algorithm!
It feels counterintuitive because normally binary search starts at 0 and len(array). But here, i isn’t just an index into ; i represents the exact count of elements we pick from to form the left half.
Here is the straightforward mathematical reason why this range is strictly necessary.
1. The Core Equation
To form the left half, we must pick elements from array and elements from array such that:
Now, we have physical limits on how many elements we can take from each array:
-
Limits on (Array ): You can’t take negative elements, and you can’t take more elements than actually has ().
-
Limits on (Array ): Similarly, you can’t take negative elements from , and you can’t take more than actually has ().
2. Deriving low and high
Since , we plug that into the second inequality ():
Let’s break this double inequality down into two separate parts to isolate :
Part A: Solving for the upper bound (high)
-
From , adding to both sides gives:
-
Combined with our physical array bound (), cannot exceed either limit:
Intuition: If , but array has elements (), you would never take 4 or 5 elements from because you only need elements in total! So can never exceed .
Part B: Solving for the lower bound (low)
-
From , subtracting and flipping signs gives:
-
Combined with our physical array bound (), cannot drop below either limit:
Intuition: Suppose , but array only has elements (). Even if you took all elements from , you are still short by elements (). Therefore, you MUST take at least elements from . Taking or from would make it physically impossible to reach .
3. Concrete Visual Examples
Example 1: Why low needs k - n
-
Array A ():
[10, 20, 30, 40, 50] -
Array B ():
[1, 2] -
(We want the 6th element overall)
If we naively set low = 0 and binary search tries (1 element from ):
-
.
-
But Array only has elements! Trying to access will cause an Index Out of Bounds crash or force negative elements.
Using the formula:
The search bounds for are restricted to [4, 5]. This guarantees we take at least 4 elements from , because can contribute at most 2 elements!
Example 2: Why high needs min(k, m)
-
Array A ():
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] -
Array B ():
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20] -
(We want the 2nd element overall)
If we naively set high = m = 10 and binary search tries (5 elements from ):
-
.
-
Taking elements from Array makes no sense!
Using the formula:
The search bounds for are restricted to [0, 2]. We never try to take more than 2 elements from .
Quick Mental Model to Remember
Think of as a slider control for how many items you take from Array :
-
high = min(k, m): You can’t slide above (run out of elements in ) and you shouldn’t slide above (you don’t need more than elements total). -
low = max(0, k - n): You can’t slide below (can’t take negative items) and you can’t slide below (otherwise wouldn’t have enough items to fill the rest of ).