Search in 2D Matrix in DSA C++ - Time & Space Complexity
We want to understand how the time needed to find a number in a 2D matrix changes as the matrix size grows.
Specifically, how does searching through rows and columns affect the work done?
Analyze the time complexity of the following code snippet.
bool searchMatrix(std::vector<std::vector<int>>& matrix, int target) {
int rows = matrix.size();
int cols = matrix[0].size();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (matrix[i][j] == target) {
return true;
}
}
}
return false;
}
This code checks every element in the matrix one by one to find the target number.
- Primary operation: Checking each element in the matrix.
- How many times: The outer loop runs once per row, and the inner loop runs once per column, so total checks = rows x columns.
As the matrix gets bigger, the number of checks grows by multiplying rows and columns.
| Input Size (rows x cols) | Approx. Operations |
|---|---|
| 10 x 10 | 100 checks |
| 100 x 100 | 10,000 checks |
| 1000 x 1000 | 1,000,000 checks |
Pattern observation: Doubling rows and columns causes the total work to grow by the square of the size increase.
Time Complexity: O(m x n)
This means the time to search grows proportionally with the total number of elements in the matrix.
[X] Wrong: "Since the matrix is sorted, searching is always fast like binary search."
[OK] Correct: This code checks every element without using the sorted order, so it still takes time proportional to all elements.
Understanding how nested loops affect time helps you explain and improve search methods in matrices during interviews.
"What if we use a search method that starts from the top-right corner and moves left or down based on comparisons? How would the time complexity change?"
Practice
Solution
Step 1: Understand matrix properties
Each row and column is sorted ascending, so top-right element is a good start to decide direction.Step 2: Use top-right corner to guide search
If target is less than current element, move left; if greater, move down.Final Answer:
Start from the top-right corner and move left or down based on comparison -> Option BQuick Check:
Top-right corner search = Start from the top-right corner and move left or down based on comparison [OK]
- Starting from bottom-left without adjusting moves
- Searching all elements without using sorting
- Using binary search on unsorted columns
Solution
Step 1: Understand vector initialization syntax
To create a 2D vector with 3 rows and 4 columns, use vector of vectors with inner vector size 4.Step 2: Check each option
std::vector matrix(3, std::vector<int>(4, 0)); correctly uses vector with 3 rows and inner vector of size 4 filled with 0.Final Answer:
std::vector matrix(3, std::vector<int>(4, 0)); -> Option CQuick Check:
Correct 2D vector init = std::vector matrix(3, std::vector<int>(4, 0)); [OK]
- Using wrong vector type for inner vector
- Swapping rows and columns sizes
- Trying to pass three arguments to vector constructor
std::vector matrix = {
{1, 4, 7, 11},
{2, 5, 8, 12},
{3, 6, 9, 16},
{10, 13, 14, 17}
};
int target = 5;
int row = 0, col = 3;
bool found = false;
while (row < 4 && col >= 0) {
if (matrix[row][col] == target) {
found = true;
break;
} else if (matrix[row][col] > target) {
col--;
} else {
row++;
}
}
std::cout << (found ? "Found" : "Not Found") << std::endl;Solution
Step 1: Trace the search starting at matrix[0][3]
matrix[0][3] = 11, target=5, 11 > 5 so col-- to 2.Step 2: Continue search
matrix[0][2] = 7, 7 > 5 so col-- to 1; matrix[0][1] = 4, 4 < 5 so row++ to 1; matrix[1][1] = 5 equals target, found = true.Final Answer:
Found -> Option AQuick Check:
Search finds 5 at (1,1) = Found [OK]
- Not updating row and col correctly
- Confusing comparison operators
- Assuming target not found without full search
bool searchMatrix(std::vector& matrix, int target) {
int row = 0, col = matrix[0].size() - 1;
while (row <= matrix.size() && col >= 0) {
if (matrix[row][col] == target) return true;
else if (matrix[row][col] > target) col--;
else row++;
}
return false;
}Solution
Step 1: Analyze loop boundary for row index
matrix.size() gives number of rows; valid row indices are 0 to size()-1, so row < size() is correct.Step 2: Identify off-by-one error
Using row <= matrix.size() allows row to equal size(), causing out-of-bounds access.Final Answer:
The while loop condition should use < instead of <= for row -> Option AQuick Check:
Row index must be less than size() [OK]
- Using <= causing out-of-bounds errors
- Incorrect initial column index
- Returning false too early inside loop
Solution
Step 1: Understand matrix sorted property
Rows and columns sorted ascending allows efficient traversal from bottom-left.Step 2: Use bottom-left traversal to count elements
Start at bottom-left; if element <= target, all elements above in that column are <= target, move right and add count; else move up.Step 3: Compare efficiency
This approach visits at most m+n elements, better than binary search on each row or full traversal.Final Answer:
Start from bottom-left and move up or right to count (O(m+n)) -> Option DQuick Check:
Bottom-left traversal counts in O(m+n) [OK]
- Using full traversal causing O(m*n) time
- Applying binary search on unsorted columns
- Flattening matrix unnecessarily increasing complexity
Ready to prove it?
Pass the test and this pattern moves unknown
