Back to Arrays
Q105Question 105 of 109

Median of Two Sorted Arrays: Binary Search Partition

Key Concepts
  • Binary-search a partition in the smaller array; derive the complementary partition in the larger array.
  • The partition is correct when every element on the left side is less than or equal to every element on the right side.
  • For odd totals, the median is the max of the two left-side values; for even totals, it is the average of the left max and right min.
  • Always search the shorter array to bound time at O(log(min(m, n))) and keep the derived partition in bounds.
  • Use negative and positive infinity as sentinels at the edges to handle empty partitions without special branches.
  • The brute-force merge approach is O(m + n) and simpler, but the binary search approach is the optimal answer.

Definition

Binary-search a partition of the smaller array so the two combined halves are balanced; read the median at the boundary.
  • Partition approach – draw a virtual cut through both arrays so the left combined half and right combined half have equal counts.
  • Binary search – search the cut position in the smaller array; derive the cut in the larger array from the half-length formula.
  • Balance condition – the partition is correct when left-max of A <= right-min of B and left-max of B <= right-min of A.
  • Sentinel values – use negative/positive infinity at array edges to handle empty partitions cleanly.
  • Complexity – O(log(min(m, n))) time, O(1) space.

At the National Bank of India, two sorted ledgers from the savings and current-account systems must be combined to find the median transaction amount. Instead of merging both fully, a clerk draws a vertical cut through both ledgers at once so the total number of rows on the left equals the number on the right, and every value on the left is no larger than every value on the right. The median sits at the boundary.

Understanding the Concepts

What is the problem?

Given two sorted arrays, find the median of the combined sorted order without merging them. The solution must run in O(log(min(m, n))) time.

At the National Bank of India, the analytics team needs the median transaction amount across two sorted datasets from two different banking systems.

What is the brute-force approach?

Merge both arrays in O(m + n) and read the middle element. This works but does not meet the logarithmic time requirement.

JAVA
// Brute force: O(m + n)
int[] merged = mergeSorted(a, b);
int total = merged.length;
if (total % 2 == 1) return merged[total / 2];
else return (merged[total / 2 - 1] + merged[total / 2]) / 2.0;

How does the binary search partition work?

Always search the shorter array (call it A of length m). Pick a cut position i in A, then the cut in B is j = (m + n + 1) / 2 - i. This ensures the left side has exactly half the total elements.

JAVA
package com.bank.analytics;

public class MedianTwoSortedArrays {
    public static double findMedian(int[] a, int[] b) {
        if (a.length > b.length) return findMedian(b, a);

        int m = a.length, n = b.length;
        int low = 0, high = m;

        while (low <= high) {
            int i = (low + high) / 2;
            int j = (m + n + 1) / 2 - i;

            int aLeftMax  = (i == 0) ? Integer.MIN_VALUE : a[i - 1];
            int aRightMin = (i == m) ? Integer.MAX_VALUE : a[i];
            int bLeftMax  = (j == 0) ? Integer.MIN_VALUE : b[j - 1];
            int bRightMin = (j == n) ? Integer.MAX_VALUE : b[j];

            if (aLeftMax <= bRightMin && bLeftMax <= aRightMin) {
                if ((m + n) % 2 == 1) {
                    return Math.max(aLeftMax, bLeftMax);
                } else {
                    return (Math.max(aLeftMax, bLeftMax)
                          + Math.min(aRightMin, bRightMin)) / 2.0;
                }
            } else if (aLeftMax > bRightMin) {
                high = i - 1;
            } else {
                low = i + 1;
            }
        }
        throw new IllegalArgumentException("Input arrays are not sorted");
    }

    public static void main(String[] args) {
        int[] savings = {100, 300, 500, 700};
        int[] current = {200, 400, 600, 800};
        System.out.println("Median: " + findMedian(savings, current));
    }
}
TEXT
Median: 450.0

Why always search the shorter array?

Searching the shorter array bounds the binary search range to O(log(min(m, n))). It also guarantees that the derived cut j stays within bounds of the longer array. If you searched the longer array, j could go negative.

How do the sentinel values work?

When i = 0, the left side of A is empty, so aLeftMax should be negative infinity (will never violate the condition). When i = m, the right side of A is empty, so aRightMin should be positive infinity. This eliminates special-case branches.

JAVA
int aLeftMax  = (i == 0) ? Integer.MIN_VALUE : a[i - 1];
int aRightMin = (i == m) ? Integer.MAX_VALUE : a[i];

What is the partition balance condition?

DIAGRAM
The partition is correct when:
- `aLeftMax <= bRightMin` (everything on A's left is <= everything on B's right)
- `bLeftMax <= aRightMin` (everything on B's left is <= everything on A's right)

If aLeftMax > bRightMin, the cut in A is too far right, so move high = i - 1.
If bLeftMax > aRightMin, the cut in A is too far left, so move low = i + 1.

How do you read the median from the partition?

  • Once balanced:
  • Odd total: median = max(aLeftMax, bLeftMax). The larger of the two left-edge values is the middle element.
  • Even total: median = average of max(aLeftMax, bLeftMax) and min(aRightMin, bRightMin).

What is the time and space complexity?

| Approach | Time | Space |
|---|---|---|
| Binary search partition | O(log(min(m, n))) | O(1) |
| Merge and find middle | O(m + n) | O(m + n) |

What are common mistakes?

Searching the longer array, which can cause j to go negative.

JAVA
// Wrong: if a is longer and i is large, j = (m+n+1)/2 - i can be negative
int j = (m + n + 1) / 2 - i; // j < 0 -> ArrayIndexOutOfBoundsException

// Correct: always make a the shorter array
if (a.length > b.length) return findMedian(b, a);

What are the edge cases?

  • One array is empty: the median is the middle of the other array.
  • Both arrays have one element: median is their average (even total) or the smaller (odd total with duplication).
  • All elements of A are smaller than all of B: the partition puts all of A on the left.
  • Arrays of very different lengths: the binary search still works because we search the shorter one.

What should a senior engineer know?

This is one of the hardest binary search problems and a classic LeetCode hard. The key insight is that finding the median is equivalent to finding the correct partition. The partition approach generalizes to finding the kth element in two sorted arrays.

For BigDecimal amounts, use compareTo for comparisons and add().divide(TWO) for the average.

What are common interview follow-up questions?

  • How would you find the kth smallest element instead of the median? (Adjust the half-length formula.)
  • What if there are more than two sorted arrays? (Use a min-heap to merge k arrays.)
  • What if the arrays are not sorted? (Sort first, which costs O(n log n), or use QuickSelect on the merged view.)

Visual Overview

TEXT
A = [100, 300, 500, 700]   (m=4)
B = [200, 400, 600, 800]   (n=4)
half = (4+4+1)/2 = 4

Binary search on A (shorter or equal):

low=0, high=4
  i=2, j=4-2=2
  aLeftMax=300, aRightMin=500
  bLeftMax=400, bRightMin=600
  300 <= 600 ✓  but  400 > 500 ✗ -> low = 3

low=3, high=4
  i=3, j=4-3=1
  aLeftMax=500, aRightMin=700
  bLeftMax=200, bRightMin=400
  500 > 400 ✗ -> high = 2

Wait, let me redo: low=0, high=4
  i=2, j=2: aLM=300, aRM=500, bLM=400, bRM=600
  bLM(400) > aRM(500)? No. aLM(300) > bRM(600)? No.
  Both conditions hold! Balanced.
  Even total: (max(300,400) + min(500,600)) / 2 = (400+500)/2 = 450.0
DIAGRAM
┌──────────────────────────────────────────────┐
│   Median of Two Sorted Arrays Flow            │
├──────────────────────────────────────────────┤
│                                              │
│   Ensure A is shorter (swap if needed)       │
│              │                               │
│              ▼                               │
│   Binary search: low=0, high=m               │
│   ┌──────────────────────────────┐           │
│   │ i = mid of [low, high]       │           │
│   │ j = half - i                 │           │
│   │ Check: aLM<=bRM && bLM<=aRM │           │
│   │   Yes: read median           │           │
│   │   aLM > bRM: high = i-1      │           │
│   │   bLM > aRM: low = i+1       │           │
│   └──────────────────────────────┘           │
│                                              │
│   Odd total:  max(aLM, bLM)                 │
│   Even total: avg(max(lefts), min(rights))   │
└──────────────────────────────────────────────┘

Key Takeaway

Finding the median of two sorted arrays in logarithmic time is one of the hardest binary search problems. The key idea is that you never merge the arrays. Instead, you binary-search a partition position in the shorter array and derive the complementary partition in the longer array so the left combined half and right combined half are correctly balanced.

The partition is correct when every element on the left is less than or equal to every element on the right. Once balanced, the median sits at the boundary: for an odd total, it is the larger of the two left-edge values; for an even total, it is the average of the left max and right min.

At the National Bank of India, the analytics team needed the median transaction amount across two sorted datasets from the savings and current-account systems. Merging two large datasets just to read the middle value would be wasteful, so the partition method gave the median in logarithmic time.

The details that make the code clean are sentinel values at array edges and always searching the shorter array. Sentinels handle empty partitions without branching, and searching the shorter array bounds the time and keeps the derived cut in bounds.

Remember one sentence: binary-search a partition in the shorter array so the two combined halves are balanced, and read the median at the boundary.

---

Share
Use ← → arrow keys to navigate