Given an M x N integer matrix matrix and an integer target, return true if target exists in the matrix, otherwise return false.
In this matrix:
Each row is sorted from left to right.
Each column is sorted from top to bottom.
Example 1
Input: matrix = [[1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30]], target = 5
Output: true
Explanation: 5 is present in the matrix, so the answer is true.
Example 2
Input: matrix = [[1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30]], target = 20
Output: false
Explanation: 20 does not appear anywhere in the matrix.
Brute Force Approach
The simplest thought is to just check every value one by one.
If any cell matches the target, the search can stop immediately.
This approach is useful as a starting point because it matches exactly what the problem is asking, even though it does not use the matrix properties in a smart way.
Algorithm
First, check whether the matrix is empty. This is needed so the code does not try to access a row or column that does not exist.
Traverse every row because the target can be in any part of the matrix.
Inside each row, traverse every column and compare the current value with the target.
If the current value matches the target, return
trueimmediately because the answer has been found.If the full matrix is checked and no match appears, return
falsebecause the target is not present.
Dry Run
Brute
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: /* Returns true if the target exists anywhere in the matrix. */ bool searchMatrix(vector<vector<int>>& matrix, int target) { // Stop early if the matrix has no usable cells. if (matrix.empty() || matrix[0].empty()) { return false; } for (int i = 0; i < (int)matrix.size(); i++) { for (int j = 0; j < (int)matrix[i].size(); j++) { // Return immediately because the target is found here. if (matrix[i][j] == target) { return true; } } } return false; }};// Driver code startsint main() { vector<vector<int>> matrix = { {1, 3, 5, 7}, {10, 11, 16, 20}, {23, 30, 34, 60} }; int target = 3; Solution obj; cout << (obj.searchMatrix(matrix, target) ? "true" : "false") << endl; return 0;}Complexity Analysis
Time Complexity: O(M x N), M is the number of rows and N is the number of columns, because in the worst case every cell of the matrix may need to be checked.
Space Complexity: O(1), because constant space is used.
Optimal Approach
The unlocking observation comes from choosing the right starting corner. The top-right element is a very special position.
Everything on its left is smaller.
Everything below it is larger.
That means one comparison is enough to decide one whole direction. If the current value is larger than the target, moving down makes things even larger, so that cannot help. The only useful move is left.
If the current value is smaller than the target, moving left makes things even smaller, so that cannot help either. The only useful move is down.
This is the full reason the method works. Each step removes one row or one column from consideration, so the search keeps shrinking in a very controlled way.
This pattern often feels like walking down a staircase, which is why this method is commonly called staircase search.
Algorithm
First, check whether the matrix is empty. This is needed so the search does not try to read an invalid corner position.
Start from the top-right cell using
row = 0andcol = cols - 1. This corner is chosen because it gives opposite directions: left becomes smaller and down becomes larger.Compare the current value with the target. If both values are equal, return
trueimmediately because the target has been found.If the current value is greater than the target, move left by decreasing
col. This is done because the full current column below this cell is even larger, so that column cannot contain the target at this position or below.If the current value is smaller than the target, move down by increasing
row. This is done because the full current row to the left is even smaller, so staying in that row cannot help anymore.Keep repeating this process while
rowstays inside the matrix andcolstays inside the matrix.If the search goes out of bounds, return
falsebecause every useful row or column has already been ruled out.
Key Points
This problem is not globally sorted like
Search in a 2D Matrix, so flattening into a virtual 1D array does not work here. Check the article on Search in a 2D MatrixStarting from the bottom-left corner also works for the same reason, just with opposite moves.
Dry Run
Optimal
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: /* Returns true if the target exists anywhere in the matrix. */ bool searchMatrix(vector<vector<int>>& matrix, int target) { // Stop early if the matrix has no usable cells. if (matrix.empty() || matrix[0].empty()) { return false; } // These store the matrix dimensions for boundary checks. int rows = (int)matrix.size(); int cols = (int)matrix[0].size(); // Start from the top-right corner to remove one row or column each step. int row = 0; int col = cols - 1; while (row < rows && col >= 0) { // Read the current corner value of the remaining search area. int current = matrix[row][col]; // Return immediately because the target is found here. if (current == target) { return true; } // Move left because everything below this value is even larger. if (current > target) { col--; } else { // Move down because everything left of this value is even smaller. row++; } } return false; }};// Driver code startsint main() { vector<vector<int>> matrix = { {1, 4, 7, 11, 15}, {2, 5, 8, 12, 19}, {3, 6, 9, 16, 22}, {10, 13, 14, 17, 24}, {18, 21, 23, 26, 30} }; int target = 5; Solution obj; cout << (obj.searchMatrix(matrix, target) ? "true" : "false") << endl; return 0;}Complexity Analysis
Time Complexity: O(M + N),M is the number of rows and N is the number of columns,because in each step one row or one column is removed from the search.
Space Complexity: O(1), because constant space is used.
Interview follow-up Questions
Starting from the top-left corner does not work for this strategy. If the target is larger than the number at the top-left, you have two choices to find a larger number: you can move right or you can move down. Because both directions lead to larger numbers, you cannot definitively eliminate a row or a column, which breaks the logic.
Be the first to add a comment.