LeetCopilot Logo
LeetCopilot
LeetCode Pattern/Binary Search/Binary Search on 2D Matrices: Row-Column Search and Sorted Matrix Techniques

Binary Search on 2D Matrices: Row-Column Search and Sorted Matrix Techniques

LeetCopilot Team
Dec 30, 2025
10 min read
Binary Search2D MatrixIndex MappingStaircase SearchTemplates
Master binary search on 2D matrices with two approaches: treat as 1D array for fully sorted matrices, and staircase search for row-column sorted matrices. Learn index mapping and when to use each technique.

Binary search extends naturally to 2D matrices, but the approach depends on the matrix structure. A fully sorted matrix (sorted row-by-row) requires different logic than a matrix where each row and column is sorted independently.

This guide covers both approaches, when to use each, the index mapping formula, and complete templates for 2D matrix binary search.

TL;DR

Two matrix types:

Type 1: Fully sorted (treat as 1D array)

code
[1,  3,  5,  7]
[10, 11, 16, 20]
[23, 30, 34, 60]

Sorted row-by-row → Use binary search with index mapping
Time: O(log(m × n))

Type 2: Row-column sorted (staircase search)

code
[1,  4,  7, 11]
[2,  5,  8, 12]
[3,  6,  9, 16]
[10, 13, 14, 17]

Each row sorted, each column sorted → Use staircase search
Time: O(m + n)

Type 1: Fully Sorted Matrix

Problem (LeetCode #74)

Matrix is sorted row-by-row (last element of row i < first element of row i+1).

The "Treat as 1D Array" Technique

Key insight: A fully sorted matrix is just a 1D sorted array wrapped into 2D.

Index mapping:

code
1D index → 2D coordinates:
  row = index // cols
  col = index % cols

2D coordinates → 1D index:
  index = row * cols + col

Template

python
def searchMatrix(matrix: List[List[int]], target: int) -> bool:
    """
    Search in fully sorted matrix
    
    Time: O(log(m × n))
    Space: O(1)
    """
    if not matrix or not matrix[0]:
        return False
    
    rows, cols = len(matrix), len(matrix[0])
    left, right = 0, rows * cols - 1
    
    while left <= right:
        mid = left + (right - left) // 2
        
        # Convert 1D index to 2D coordinates
        row, col = mid // cols, mid % cols
        mid_value = matrix[row][col]
        
        if mid_value == target:
            return True
        elif mid_value < target:
            left = mid + 1
        else:
            right = mid - 1
    
    return False

Example

python
matrix = [
    [1,  3,  5,  7],
    [10, 11, 16, 20],
    [23, 30, 34, 60]
]

searchMatrix(matrix, 3)  # True

# Trace:
# left=0, right=11, mid=5
#   row=5//4=1, col=5%4=1
#   matrix[1][1]=11 > 3 → right=4
# left=0, right=4, mid=2
#   row=2//4=0, col=2%4=2
#   matrix[0][2]=5 > 3 → right=1
# left=0, right=1, mid=0
#   row=0//4=0, col=0%4=0
#   matrix[0][0]=1 < 3 → left=1
# left=1, right=1, mid=1
#   row=1//4=0, col=1%4=1
#   matrix[0][1]=3 == 3 → True ✓

Type 2: Row-Column Sorted Matrix

Problem (LeetCode #240)

Each row is sorted left-to-right, each column is sorted top-to-bottom, but NOT fully sorted overall.

Why Binary Search Alone Doesn't Work

code
Matrix:
[1,  4,  7, 11]
[2,  5,  8, 12]
[3,  6,  9, 16]
[10, 13, 14, 17]

Target = 5

If we treat as 1D: [1,4,7,11,2,5,8,12,3,6,9,16,10,13,14,17]
This is NOT sorted → binary search fails

The "Staircase" Search Technique

Key insight: Start from top-right (or bottom-left) corner. From there, you can eliminate either a row or column with each comparison.

Starting from top-right:

  • If matrix[row][col] > target: eliminate column (move left)
  • If matrix[row][col] < target: eliminate row (move down)
  • If matrix[row][col] == target: found!

Why this works:

  • Top-right is smallest in its column, largest in its row
  • Can make greedy decisions

Template

python
def searchMatrix(matrix: List[List[int]], target: int) -> bool:
    """
    Search in row-column sorted matrix
    
    Time: O(m + n)
    Space: O(1)
    """
    if not matrix or not matrix[0]:
        return False
    
    rows, cols = len(matrix), len(matrix[0])
    row, col = 0, cols - 1  # Start from top-right
    
    while row < rows and col >= 0:
        if matrix[row][col] == target:
            return True
        elif matrix[row][col] > target:
            col -= 1  # Eliminate column
        else:
            row += 1  # Eliminate row
    
    return False

Example

python
matrix = [
    [1,  4,  7, 11],
    [2,  5,  8, 12],
    [3,  6,  9, 16],
    [10, 13, 14, 17]
]

searchMatrix(matrix, 5)  # True

# Trace (starting from top-right):
# row=0, col=3: matrix[0][3]=11 > 5 → col=2
# row=0, col=2: matrix[0][2]=7 > 5 → col=1
# row=0, col=1: matrix[0][1]=4 < 5 → row=1
# row=1, col=1: matrix[1][1]=5 == 5 → True ✓

When to Use Each Approach

Matrix TypeApproachTimeExample
Fully sorted row-by-rowBinary search (1D mapping)O(log(m×n))LeetCode #74
Row and column sortedStaircase searchO(m+n)LeetCode #240

Complete Code Examples

JavaScript: Fully Sorted

javascript
function searchMatrix(matrix, target) {
    if (!matrix || !matrix.length || !matrix[0].length) return false;
    
    const rows = matrix.length;
    const cols = matrix[0].length;
    let left = 0;
    let right = rows * cols - 1;
    
    while (left <= right) {
        const mid = left + Math.floor((right - left) / 2);
        const row = Math.floor(mid / cols);
        const col = mid % cols;
        const midValue = matrix[row][col];
        
        if (midValue === target) {
            return true;
        } else if (midValue < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    
    return false;
}

Java: Row-Column Sorted

java
public boolean searchMatrix(int[][] matrix, int target) {
    if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
        return false;
    }
    
    int rows = matrix.length;
    int cols = matrix[0].length;
    int row = 0;
    int col = cols - 1;
    
    while (row < rows && col >= 0) {
        if (matrix[row][col] == target) {
            return true;
        } else if (matrix[row][col] > target) {
            col--;
        } else {
            row++;
        }
    }
    
    return false;
}

Common Mistakes

Mistake 1: Wrong Index Mapping

Wrong:

python
row = mid % cols  # WRONG
col = mid // cols  # WRONG

Correct:

python
row = mid // cols  # Correct
col = mid % cols   # Correct

See guide: 2D Matrix Index Mapping

Mistake 2: Using Wrong Approach

Wrong:

python
# Using binary search on row-column sorted matrix (not fully sorted)

Correct:

python
# Use staircase search for row-column sorted

Mistake 3: Off-by-One in Dimensions

Wrong:

python
right = rows * cols  # WRONG: should be -1

Correct:

python
right = rows * cols - 1  # Correct

Practice Problems

  1. Search a 2D Matrix (#74) — Fully sorted
  2. Search a 2D Matrix II (#240) — Row-column sorted
  3. Kth Smallest Element in Sorted Matrix (#378) — Binary search on answer

FAQ

Q: Which approach is faster?

A: Binary search (O(log(m×n))) is faster than staircase (O(m+n)), but only works on fully sorted matrices.

Q: Can I use binary search on row-column sorted matrices?

A: Not directly. You'd need to binary search each row (O(m log n)) or use staircase search (O(m+n)).

Q: Why start from top-right in staircase search?

A: Top-right (or bottom-left) allows greedy elimination. Top-left or bottom-right don't work.

Q: What if the matrix is empty?

A: Handle edge cases: check if matrix, matrix[0] exist before accessing.

Conclusion

Binary search on 2D matrices requires choosing the right approach:

Fully sorted: Treat as 1D array with index mapping → O(log(m×n))
Row-column sorted: Use staircase search → O(m+n)

Master both techniques and you'll handle any 2D matrix search problem. For more details, see 2D Matrix Index Mapping and the Complete Binary Search Guide.

Want to Practice LeetCode Smarter?

LeetCopilot is a free browser extension that enhances your LeetCode practice with AI-powered hints, personalized study notes, and realistic mock interviews — all designed to accelerate your coding interview preparation.

Also compatible with Edge, Brave, and Opera

Related Tutorials