Searching & Sorting · Searching & Sorting Fundamentals

Binary Search on Two Arrays

Binary searching for the correct split point of one sorted array, with the split point of the other array determined arithmetically from it - locating a combined rank without ever merging the two arrays.

  • 5 min read
  • 8 practice questions
  • 2 graded problems
On this page
  1. Description
  2. The approach
  3. A second flavor: the median
  4. Where you'll see it
  5. Which tool for which job?
  6. Common mistakes
  7. Check yourself
  8. Key takeaways
  9. Quick revise
  10. Practice

Description

This skill finds the k-th smallest element, or the median, of two sorted arrays without merging them. Merging takes O(n + m) time and memory just to read one position. But the answer is decided by how many of the first k elements come from each array. Once you pick how many come from the first, the second array's share is fixed. That turns a two-array question into a binary search over one number, the cut in the shorter array.

We'll go from simple to more technical:

  1. The pattern: binary search the cut in the shorter array, with sentinels at the edges.
  2. A second flavor: the median, for odd and even totals.
  3. Where rank-based splitting shows up (merging shards, distributed quantiles).
  4. What breaks it: searching the longer array, missing sentinels, merging anyway.

The approach

Java

int kthElement(int[] a, int[] b, int k) {             // a is the shorter array
    if (a.length > b.length) return kthElement(b, a, k);
    int lo = Math.max(0, k - b.length), hi = Math.min(k, a.length);
    while (lo <= hi) {
        int cutA = lo + (hi - lo) / 2;                 // take cutA elements from a...
        int cutB = k - cutA;                           // ...so the rest must come from b
        int leftA  = cutA == 0 ? Integer.MIN_VALUE : a[cutA - 1];
        int leftB  = cutB == 0 ? Integer.MIN_VALUE : b[cutB - 1];
        int rightA = cutA == a.length ? Integer.MAX_VALUE : a[cutA];
        int rightB = cutB == b.length ? Integer.MAX_VALUE : b[cutB];
        if (leftA <= rightB && leftB <= rightA) return Math.max(leftA, leftB);   // a valid split
        if (leftA > rightB) hi = cutA - 1;             // took too many from a
        else lo = cutA + 1;                            // took too few from a
    }
    return -1;                                         // unreachable for valid k
}

Python

def kth_element(a: list[int], b: list[int], k: int) -> int:   # a is the shorter array
    if len(a) > len(b):
        return kth_element(b, a, k)
    lo, hi = max(0, k - len(b)), min(k, len(a))
    while lo <= hi:
        cut_a = (lo + hi) // 2                     # take cut_a elements from a...
        cut_b = k - cut_a                          # ...so the rest must come from b
        left_a = a[cut_a - 1] if cut_a > 0 else float("-inf")   # a[-1] would be the LAST element
        left_b = b[cut_b - 1] if cut_b > 0 else float("-inf")
        right_a = a[cut_a] if cut_a < len(a) else float("inf")
        right_b = b[cut_b] if cut_b < len(b) else float("inf")
        if left_a <= right_b and left_b <= right_a:
            return max(left_a, left_b)             # a valid split
        if left_a > right_b:
            hi = cut_a - 1                         # took too many from a
        else:
            lo = cut_a + 1                         # took too few from a
    return -1                                      # unreachable for valid k

A split is correct when everything on the left of both cuts is <= everything on the right - then the left side holds exactly the k smallest values, and the k-th is the larger of the two left edges. If a's left edge is too big, fewer elements should come from a; if b's is too big, more should. The bounds keep cutB within b: at least k - b.length elements must come from a, and at most min(k, a.length) can.

A second flavor: the median

The median is the same search with k = (n + m + 1) / 2, the size of the left half. With an odd total, the median is the largest left element; with an even total, it's the average of the largest left element and the smallest right element:

Java

// at a valid split with k = (n + m + 1) / 2:
double median = ((n + m) % 2 == 1)
        ? Math.max(leftA, leftB)
        : (Math.max(leftA, leftB) + (double) Math.min(rightA, rightB)) / 2.0;

Python

# at a valid split with k = (n + m + 1) // 2:
median = (max(left_a, left_b) if (n + m) % 2 == 1
          else (max(left_a, left_b) + min(right_a, right_b)) / 2)   # / is true division

For [1, 3] and [2] that's 2.0; for [1, 2] and [3, 4], (2 + 3) / 2 = 2.5. Converting to double before adding avoids overflowing two large ints. (In Python, ints can't overflow and / always divides exactly - // would floor 2.5 to 2.)

Where you'll see it

Distributed databases and analytics engines compute percentiles and top-k across shards that are each sorted, without shipping and merging all the data; the same "how many from each side" split generalizes to k sorted sources (with a binary search over the value instead of the count). External sorting and merge-based query plans rely on the same reasoning about ranks across sorted runs.

Which tool for which job?

You needUse
k-th smallest of two sorted arraysbinary search the cut in the shorter array
The same, simpler to get rightk/2 elimination: drop k/2 elements per step
Median of two sorted arraysk = (n + m + 1) / 2, then odd or even
k-th smallest across many sorted shardsbinary search on the value, counting per shard
Many queries on the same arraysmerge once, then index

Common mistakes

MistakeWhat happensDo this instead
Searching the longer arraythe second cut runs out of rangesearch the shorter one, lo = max(0, k - len(b))
No sentinels for empty sidesin Python, a[-1] silently gives 20 instead of 3-infinity on the left, +infinity on the right
(leftMax + rightMin) / 2.0 with ints-9.7483648E7 for two large valuesconvert to double before adding
Merging to be safeO(n + m) time and memorythe partition search

Check yourself

Try to answer before opening each one - recalling beats re-reading.

1. Why is it enough to binary-search only one array's cut?

Show answer

The two cuts must add up to k: taking cutA elements from a forces cutB = k - cutA from b. So there's only one free choice, and each check tells you whether to take more or fewer from a.

2. What makes a split valid, and what's the k-th element then?

Show answer

a's left edge <= b's right edge and b's left edge <= a's right edge - so every left element is <= every right element and the left side is exactly the k smallest. The k-th smallest is max(leftA, leftB).

3. How does the median follow from the same search?

Show answer

Search with k = (n + m + 1) / 2. For an odd total the median is max(leftA, leftB); for an even total it's the average of max(leftA, leftB) and min(rightA, rightB) - computed in double so the sum can't overflow.

Key takeaways

  • Choosing how many of the first k come from one array fixes the other array's share.
  • Binary-search the shorter array's cut, with bounds max(0, k - m) to min(k, n).
  • Valid split: both left edges <= both right edges; the k-th element is the larger left edge.
  • Sentinels (MIN_VALUE, MAX_VALUE) handle empty sides without special cases.
  • The median is the same search with k = (n + m + 1) / 2, plus the odd/even rule.

Quick revise

The whole skill on one page, for the night before an interview.

This page puts the lesson and the deep dive together. Skim it before practice or an interview, and go back to the full lesson for anything you don't recognize.

Pick the tool

You needUse
k-th of two arrayspartition search on the shorter
Simpler cross-checkk/2 elimination
Mediank = (n + m + 1)/2, odd/even
Many shardsbinary search the value, sum the counts

Snippets worth knowing by heart

Java

int lo = Math.max(0, k - b.length), hi = Math.min(k, a.length);   // a is the shorter array
while (lo <= hi) {
    int ca = (lo + hi) >>> 1, cb = k - ca;
    int la = ca > 0 ? a[ca - 1] : Integer.MIN_VALUE, ra = ca < a.length ? a[ca] : Integer.MAX_VALUE;
    int lb = cb > 0 ? b[cb - 1] : Integer.MIN_VALUE, rb = cb < b.length ? b[cb] : Integer.MAX_VALUE;
    if (la <= rb && lb <= ra) return Math.max(la, lb);
    if (la > rb) hi = ca - 1; else lo = ca + 1;
}

Python

lo, hi = min_value, max_value            # k-th smallest across sorted shards
while lo < hi:
    mid = (lo + hi) // 2
    if sum(bisect.bisect_right(s, mid) for s in shards) >= k:
        hi = mid
    else:
        lo = mid + 1

The traps

  • Searching the longer array: the second cut runs out of range. Search the shorter one.
  • Missing sentinels: an empty side breaks the comparisons, and in Python a[-1] silently reads the last value. Use infinities.
  • Int addition before averaging: two large ints overflow before the division. Convert to double before adding.
  • Merging anyway: a merge costs O(n + m) time and memory. The partition search is O(log min(n, m)).

Staff-level points, one line each

  • Partition search, k/2 elimination and merging agreed on 1,000 random cases.
  • 1,000,000 + 100 elements, k = 600,000: both methods found 1,199,798 in 7 and 2 steps.
  • No sentinel in Python: the median of [10, 20] and [1, 2, 3] came out as 20 instead of 3.
  • Java (2e9 + 2.1e9) / 2.0 with int addition gave -9.7483648E7.
  • 8 shards: median 496,896 in 20 rounds of counts, matching a merge.

Say it in an interview

  • "Choosing how many come from the shorter array fixes the rest, so I binary search that cut."
  • "Sentinels handle empty sides."
  • "For a cross-check, k/2 elimination is simpler."
  • "With many shards, I binary search the value and add up per-shard counts."

Practice

This skill comes with 8 multiple-choice questions that tell you which misconception a wrong answer reveals and 2 graded problems. Your answers are graded and your mastery is tracked, so you'll know when the skill holds up. Running code and saving progress need a free account.

Practice Binary Search on Two Arrays free

Kth Element of Two Sorted Arrays

HardProCoding problemJava · Python

Given two sorted arrays arr1 and arr2, and an integer k, return the k-th smallest element (counting from 1) in the combined sorted sequence of both arrays, without actually merging them.

The full statement, the examples and the hidden test suite are part of AI Proof Engineers Pro.

Median of Two Sorted Arrays

HardProCoding problemJava · Python

Two sorted arrays together make one longer sorted sequence. Return the median of that sequence (the middle value, or the average of the two middle values) without merging the arrays.

The full statement, the examples and the hidden test suite are part of AI Proof Engineers Pro.

Practice Binary Search on Two Arrays free

No card needed. Lessons, practice questions and easy problems are free forever.

Free plan, no card · 7-day Pro trial · Cancel anytime