class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if (matrix.empty() || matrix[0].empty()) return false;
int m = matrix.size(); // 行数
int n = matrix[0].size(); // 列数
int row = 0; // 从右上角开始
int col = n - 1;
while (row < m && col >= 0) {
if (matrix[row][col] == target) {
return true;
} else if (matrix[row][col] > target) {
col--; // 当前值太大,向左移动
} else {
row++; // 当前值太小,向下移动
}
}
return false;
}
};
复杂度分析:
维度
复杂度
说明
时间复杂度
O(m + n)
每次移动一行或一列,最多移动 m+n 次
空间复杂度
O(1)
只用了两个指针
为什么不能从左上角开始?
如果从左上角 matrix[0][0] 开始:
matrix[0][0] 是当前行最小 ,也是当前列最小
如果 target > matrix[0][0],你不知道是该往右还是往下(两个方向都可能更大)
无法做出唯一决策
同理,右下角也不行(它是当前行最大、当前列最大,两个方向都可能更小)。
只有右上角和左下角可以,因为它们一个是"行最大列最小",一个是"行最小列最大",能做出唯一决策。
另一种写法:从左下角开始
cpp复制代码
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if (matrix.empty() || matrix[0].empty()) return false;
int m = matrix.size();
int n = matrix[0].size();
int row = m - 1; // 从左下角开始
int col = 0;
while (row >= 0 && col < n) {
if (matrix[row][col] == target) {
return true;
} else if (matrix[row][col] > target) {
row--; // 当前值太大,向上移动
} else {
col++; // 当前值太小,向右移动
}
}
return false;
}
};