给定M×N矩阵,每一行、每一列都按升序排列,请编写代码找出某元素。
示例:
现有矩阵 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,返回 true。
给定 target = 20,返回 false。
这道题,确实可以算作一道中等题。它一共有三种解决方案,一种方法的时间复杂度都要低于前面一种的时间复杂度。并且,每一种都有它独特的地方在。我想,这就是这道题的魅力所在。
接下来,就让我来为你讲述,这道题的三种方法究竟是哪三种方法。
顾名思义,就是顺序查找,暴力破解。我们用两个双层for循环去解决它。
for (const auto& row: matrix)
具体的代码如下:
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if(matrix.empty()) return false;
for (const auto& row: matrix) {
for (int element: row) {
if (element == target) {
return true;
}
}
}
return false;
}
};
时间复杂度:O(mn) 其中m是矩阵的行数,n是矩阵的列数
空间复杂度:O(1)
具体的代码如下:
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
for(int i = 0; i < matrix.size(); ++i){
int left = 0;
int right = matrix[0].size() - 1;
while(left <= right){
int mid = (left + right) / 2;
if(matrix[i][mid] == target) return true;
else if(matrix[i][mid] < target) left = mid +1;
else right = mid - 1;
}
}
return false;
}
};
时间复杂度:O(m * log(n)) 其中m是矩阵的行数,n是矩阵的列数
空间复杂度:O(1)
具体的代码如下:
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if(matrix.empty()) return false;
int row = 0;
int col = matrix[0].size() - 1;
while(row < matrix.size() && col >= 0){
if(matrix[row][col] > target) --col;
else if(matrix[row][col] < target) ++row;
else return true;
}
return false;
}
};
时间复杂度:在这个解决方案中,我们从右上角开始搜索,并在每次迭代中排除一行或一列。在最坏的情况下,我们可能需要遍历所有的行和列,因此时间复杂度为 O(M+N),其中 M 是矩阵的行数,N 是矩阵的列数。
空间复杂度:这个算法没有使用额外的数据结构来存储数据,只使用了几个整数变量(如 row 和 col),因此空间复杂度为 O(1)。
这个优化方案相对于二分查找方案,在时间复杂度上有所改进,而空间复杂度保持不变。
这道题用到了二分查找法与观察法来解决矩阵问题,是一道夯实基础的好题。
觉得我写的还行的小伙伴们请给我点一个赞,点一下关注,谢谢!你们的赞与关注就是对我持续输出优质内容的最大鼓励!