Search in 2D Matrix in DSA Python - Time & Space Complexity
We want to understand how the time needed to find a number in a 2D matrix changes as the matrix grows.
How does the search time grow when the matrix gets bigger?
Analyze the time complexity of the following code snippet.
def search_matrix(matrix, target):
for row in matrix:
for num in row:
if num == target:
return True
return False
This code checks each number in the matrix one by one to find the target.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Checking each element in the matrix.
- How many times: Once for every element in all rows and columns.
As the matrix size grows, the number of checks grows with the total number of elements.
| Input Size (n x m) | Approx. Operations |
|---|---|
| 10 x 10 | 100 checks |
| 100 x 100 | 10,000 checks |
| 1000 x 1000 | 1,000,000 checks |
Pattern observation: The operations grow roughly by the total number of elements, multiplying rows and columns.
Time Complexity: O(n * m)
This means the time to search grows directly with the total number of elements in the matrix.
[X] Wrong: "Since each row is sorted, searching one row is O(log m), so overall search is O(n log m)."
[OK] Correct: This code checks every element without using the sorted property, so it actually looks at all elements, making it O(n * m).
Understanding how nested loops affect time helps you explain and improve search methods in matrices during interviews.
"What if the matrix rows and columns are sorted and we use a smarter search method? How would the time complexity change?"
Practice
Solution
Step 1: Understand matrix properties and use top-right corner
Each row and column is sorted ascending, so top-right element is largest in its row and smallest in its column. If target is less than current element, move left; if greater, move down.Final Answer:
Start from top-right corner and move left or down based on comparison -> Option AQuick Check:
Top-right start = efficient search [OK]
- Starting from bottom-left without adjusting logic
- Searching all elements linearly
- Using binary search on each row without considering columns
matrix with 3 rows and 4 columns filled with zeros?Solution
Step 1: Understand list comprehension for 2D matrix and check options
Use nested list comprehension [[0 for _ in range(4)] for _ in range(3)] to create independent 3 rows with 4 zeros each. A shares references, B wrong dimensions, C syntax invalid.Final Answer:
matrix = [[0 for _ in range(4)] for _ in range(3)] -> Option DQuick Check:
Nested list comprehension = correct matrix init [OK]
- Using [[0]*4]*3 causes shared references
- Multiplying lists incorrectly
- Swapping rows and columns in comprehension
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 3
row, col = 0, len(matrix[0]) - 1
found = False
while row < len(matrix) and col >= 0:
if matrix[row][col] == target:
found = True
break
elif matrix[row][col] > target:
col -= 1
else:
row += 1
print(found)Solution
Step 1: Trace starting position and comparisons until target found
Start at top-right: matrix[0][3] = 7 > 3, move left to col=2; matrix[0][2] = 5 > 3, move left col=1; matrix[0][1] = 3 == target, found = True.Final Answer:
True -> Option CQuick Check:
Found target 3 = True [OK]
- Confusing row and column indices
- Not updating row or col correctly
- Assuming linear search needed
def search_matrix(matrix, target):
row = 0
col = len(matrix[0])
while row < len(matrix) and col >= 0:
if matrix[row][col] == target:
return True
elif matrix[row][col] > target:
col -= 1
else:
row += 1
return FalseSolution
Step 1: Check initial column index and correct start
col is set to len(matrix[0]) which is out of range (indexing starts at 0). It should be len(matrix[0]) - 1 to start at last valid column index.Final Answer:
col should start at len(matrix[0]) - 1, not len(matrix[0]) -> Option AQuick Check:
Index out of range fix = col start - 1 [OK]
- Starting col at length causes IndexError
- Changing row start incorrectly
- Using wrong loop condition
Solution
Step 1: Analyze time complexities and correct approach
Full traversal O(m*n), top-right single pass misses duplicates off the path, flatten O(m*n); binary search on each row finds leftmost/rightmost target positions to compute count per row, total O(m*log n) efficient and correct.Final Answer:
Use binary search on each row and sum counts (O(m*log n)) -> Option BQuick Check:
Binary per row = efficient count [OK]
- Using full traversal wasting time
- Flattening matrix loses sorted structure
- Top-right movement misses off-path duplicates
Ready to prove it?
Pass the test and this pattern moves unknown
