Search a 2D Matrix Solution
Given an m ร n matrix with sorted rows and each row's first element greater than the previous row's last, determine if a target exists.
Problem Statement
Write an efficient algorithm that searches for a value target in an m ร n integer matrix. Each row is sorted left-to-right, and each row's first integer is greater than the previous row's last integer.
Brute Force โ O(m ยท n)
Scan every element. A better approach: binary search the rows to find the right row, then binary search within it โ O(log m + log n). But the cleanest optimal solution treats the entire matrix as a single sorted array.
Flattened Binary Search โ O(log(mยทn))
Treat the 2D matrix as a virtual 1D sorted array. Index k maps to matrix[k / n][k % n]. Run standard binary search on indices 0 to mยทn โ 1.
row = mid / cols, col = mid % cols. Binary search works on this virtual flat array.
- Step 1:
left = 0,right = m*n - 1. - Step 2: Compute
mid. Map:row = mid / n,col = mid % n. - Step 3: Compare
matrix[row][col]to target. Standard binary search logic.
- First binary search rows to find which row the target belongs to (compare target to row's first and last element).
- Then binary search within that row. Same O(log m + log n) = O(log(mยทn)) complexity, but slightly more code.
Visual Walkthrough
Trace: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3:
Code โ Java & Python
Complexity Analysis
| Approach | Time | Space | Trade-off |
|---|---|---|---|
| Brute Force | O(m ยท n) | O(1) | Scans every element |
| Staircase (top-right) | O(m + n) | O(1) | Works for LC 240 too but slower |
| Flattened Binary Search โ optimal | O(log(mยทn)) | O(1) | Virtual 1D array via index math |
Edge Cases & Pitfalls
| Case | Input | Why It Matters |
|---|---|---|
| 1ร1 matrix | [[5]], target=5 | Single element โ mid=0 โ found. |
| Single row | [[1,3,5]] | Degenerates to standard 1D binary search. |
| Single column | [[1],[3],[5]] | n=1; mid/1=row, mid%1=0. Works correctly. |
| Not found | target=4 | Falls between 3 and 5 โ L crosses R โ false. |
mid / m instead of mid / n for the row. The number of columns (n) determines how many indices fit per row. row = mid / n, col = mid % n. Swapping m and n gives wrong coordinates.