Bird
Raised Fist0
Interview Prepmodified-binary-searchmediumAmazonMicrosoftFacebook

Search a 2D Matrix

Choose your preparation mode4 modes available
📋
Problem

Imagine you have a large spreadsheet sorted row-wise and column-wise, and you want to quickly find if a certain value exists without scanning every cell.

Given an m x n matrix where each row is sorted in ascending order and the first integer of each row is greater than the last integer of the previous row, write a function that returns true if a given target value exists in the matrix, and false otherwise.

m == matrix.lengthn == matrix[i].length1 ≤ m, n ≤ 10^5 (total elements ≤ 10^5)-10^9 ≤ matrix[i][j], target ≤ 10^9
Edge cases: Empty matrix → falseMatrix with one element equal to target → trueMatrix with one element not equal to target → false
</>
IDE
def searchMatrix(matrix: list[list[int]], target: int) -> bool:public boolean searchMatrix(int[][] matrix, int target)bool searchMatrix(vector<vector<int>>& matrix, int target)function searchMatrix(matrix, target)
def searchMatrix(matrix, target):
    # Write your solution here
    pass
class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        // Write your solution here
        return false;
    }
}
#include <vector>
using namespace std;

bool searchMatrix(vector<vector<int>>& matrix, int target) {
    // Write your solution here
    return false;
}
function searchMatrix(matrix, target) {
    // Write your solution here
}
Coming soon
0/9
Common Bugs to Avoid
Wrong: falseIncorrect index mapping from 1D mid to 2D matrix coordinates causing missed target.✅ Calculate row = mid // n and col = mid % n correctly before comparing matrix[row][col] to target.
Wrong: trueNo check for empty matrix or empty rows, causing false positives or errors.✅ Add guard clause: if not matrix or not matrix[0]: return false before binary search.
Wrong: trueFailing to return false when target is outside matrix value range (less than smallest or greater than largest).✅ Add early return if target < matrix[0][0] or target > matrix[m-1][n-1].
Wrong: falseBinary search loop conditions or mid updates incorrect causing infinite loops or missed matches in single-element or duplicate matrices.✅ Ensure low <= high loop condition and update low = mid + 1 or high = mid - 1 correctly.
Wrong: TLEUsing O(m*n) brute force or O(m*log n) binary search per row instead of O(log(m*n)) binary search over entire matrix.✅ Implement binary search treating matrix as a flattened sorted array with index mapping.
✓
Test Cases
t1_01basic
Input{"matrix":[[1,3,5,7],[10,11,16,20],[23,30,34,60]],"target":3}
Expectedtrue

3 is present in the first row, second column.

t1_02basic
Input{"matrix":[[1,2,3,4],[5,6,7,8],[9,10,11,12]],"target":10}
Expectedtrue

10 is present in the third row, second column.

t2_01edge
Input{"matrix":[],"target":1}
Expectedfalse

Empty matrix contains no elements, so target cannot be found.

t2_02edge
Input{"matrix":[[5]],"target":5}
Expectedtrue

Single element matrix where element equals target.

t2_03edge
Input{"matrix":[[5]],"target":3}
Expectedfalse

Single element matrix where element does not equal target.

t3_01corner
Input{"matrix":[[1,3,5],[7,9,11],[13,15,17]],"target":0}
Expectedfalse

Target smaller than smallest element in matrix.

t3_02corner
Input{"matrix":[[1,3,5],[7,9,11],[13,15,17]],"target":18}
Expectedfalse

Target larger than largest element in matrix.

t3_03corner
Input{"matrix":[[1,1,1],[1,1,1],[1,1,1]],"target":1}
Expectedtrue

All elements identical and equal to target.

t4_01performance
Input{"_description":"n=100000 at constraint boundary - executor generates this"}
⏱ Performance - must finish in 2000ms

Matrix with 100000 elements; O(log(m*n)) binary search must complete within 2 seconds.

Practice

(1/5)
1. Given the following code for finding a peak element, what is the final output when the input array is [1, 3, 2]?
def findPeakElement(nums):
    def binarySearch(low, high):
        if low == high:
            return low
        mid = (low + high) // 2
        if nums[mid] < nums[mid + 1]:
            return binarySearch(mid + 1, high)
        else:
            return binarySearch(low, mid)
    return binarySearch(0, len(nums) - 1)

print(findPeakElement([1, 3, 2]))
easy
A. None of the above
B. 0
C. 2
D. 1

Solution

  1. Step 1: Trace first call binarySearch(0, 2)

    mid = (0+2)//2 = 1; nums[1]=3, nums[2]=2; since 3 > 2, recurse binarySearch(0,1)
  2. Step 2: Trace second call binarySearch(0, 1)

    mid = (0+1)//2 = 0; nums[0]=1, nums[1]=3; since 1 < 3, recurse binarySearch(1,1)
  3. Step 3: Trace third call binarySearch(1, 1)

    low == high, return 1
  4. Final Answer:

    Option D -> Option D
  5. Quick Check:

    Returned index 1 corresponds to peak element 3 [OK]
Hint: Check mid and mid+1 comparison carefully [OK]
Common Mistakes:
  • Returning mid instead of low/high
  • Off-by-one in mid calculation
  • Confusing which half to recurse
2. Given the following code snippet, what is the final output when running with piles = [3, 6, 7, 11] and h = 8?
from math import ceil

def can_finish(piles, speed, h):
    hours = 0
    for pile in piles:
        hours += ceil(pile / speed)
        if hours > h:
            return false
    return true

def minEatingSpeed(piles, h):
    low, high = 1, max(piles)
    while low < high:
        mid = (low + high) // 2
        if can_finish(piles, mid, h):
            high = mid
        else:
            low = mid + 1
    return low

piles = [3,6,7,11]
h = 8
print(minEatingSpeed(piles, h))
easy
A. 3
B. 4
C. 5
D. 6

Solution

  1. Step 1: Trace binary search iterations

    Initial low=1, high=11. mid=6: can_finish with speed=6 returns true (hours=3+1+2+2=8 ≤8), so high=6. Next mid=(1+6)//2=3: can_finish speed=3 returns false (hours=1+2+3+4=10 >8), so low=4. Next mid=(4+6)//2=5: can_finish speed=5 returns true (hours=1+2+2+3=8 ≤8), so high=5. Next mid=(4+5)//2=4: can_finish speed=4 returns true (hours=1+2+2+3=8 ≤8), so high=4. Now low=4, high=4, loop ends.
  2. Step 2: Return final low value

    The minimum speed is 4.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Tracing confirms minimum speed is 4 [OK]
Hint: Check feasibility at mid speeds carefully [OK]
Common Mistakes:
  • Off-by-one in binary search boundaries
  • Miscounting hours with ceil division
3. Consider the following Python function maxDistanceOptimized that finds the largest minimum distance to place m balls in sorted positions. Given position = [1, 2, 4, 8] and m = 3, what is the final returned value?
easy
A. 2
B. 4
C. 3
D. 1

Solution

  1. Step 1: Trace binary search boundaries

    Initial low=1, high=7 (8-1). Mid=4: can_place(4)? Positions: 1,2,4,8. Place first ball at 1, next at 8 (8-1=7≥4), count=2 < m=3 -> False.
  2. Step 2: Adjust boundaries and find final result

    high=3, mid=2: can_place(2)? Place at 1, then 4 (4-1=3≥2), then 8 (8-4=4≥2), count=3 -> True. low=3, mid=3: can_place(3)? Place at 1, then 4 (3≥3), then 8 (4≥3), count=3 -> True. low=4, high=3 ends loop. Result=3.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Final max minimum distance is 3 [OK]
Hint: Check feasibility at mid distances carefully [OK]
Common Mistakes:
  • Off-by-one in binary search boundaries
  • Miscounting balls placed in can_place
4. What is the time complexity of the min-heap based approach to find the kth smallest element in an n x n sorted matrix, where k ≤ n²? Assume the heap operations take O(log n) time.
medium
A. O(k log n)
B. O(k log k)
C. O(n log k)
D. O(n^2 log n)

Solution

  1. Step 1: Analyze heap size and operations

    The heap holds at most n elements (one from each row), so heap operations cost O(log n).
  2. Step 2: Count total heap operations

    We pop and push at most k times, so total time is O(k log n).
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Heap size bounded by n, operations proportional to k [OK]
Hint: Heap size limited to n, not k or n² [OK]
Common Mistakes:
  • Assuming heap size grows to k or n²
  • Confusing k and n in log factors
  • Thinking complexity is O(n^2 log n)
5. Suppose Koko can eat bananas from multiple piles simultaneously each hour (i.e., she can split her eating speed across piles). How does this change the approach to find the minimum eating speed to finish within h hours?
hard
A. Feasibility check simplifies to total bananas ≤ speed * h, so minimum speed = ceil(total / h)
B. We must use dynamic programming to consider all pile combinations per hour
C. The original binary search with feasibility check still applies without changes
D. Binary search is invalid; a greedy approach is required instead

Solution

  1. Step 1: Understand the new eating model

    Koko can split speed across piles simultaneously, so total bananas eaten per hour equals speed.
  2. Step 2: Simplify feasibility condition

    To finish in h hours, total bananas ≤ speed * h, so minimum speed = ceil(total bananas / h).
  3. Step 3: Conclude algorithm change

    No binary search needed; direct calculation suffices.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Splitting speed removes per-pile constraints, simplifying problem [OK]
Hint: Splitting speed means total bananas divided by hours [OK]
Common Mistakes:
  • Applying original binary search blindly
  • Overcomplicating with DP
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard