题目

分析
思路一
并不高效的搜索,先遍历第一列和第一行,由于是升序数组,所以分别找出小于target的首元素对应的行、列,然后再遍历这些行列交叉的节点元素值与target作比较,返回结果。
代码
cpp
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int m = matrix.size();
int n = matrix[0].size();
if(matrix[0][0]>target||matrix[m-1][n-1]<target){//如果数组最小的数都比target大或者最大的数都比target小,那么直接返回假
return false;
}
vector<int>line;
vector<int>col;
for(int i = 0;i<n;i++){//寻找首元素小于target,target可能所在的列
if(matrix[0][i]==target)return true;
else if(matrix[0][i]<target){
col.push_back(i);
}
else continue;
}
for(int i = 0;i<m;i++){//寻找首元素小于target,target可能所在的行
if(matrix[i][0]==target)return true;
else if(matrix[i][0]<target){
line.push_back(i);
}
else continue;
}
for(auto i:line){//遍历交叉节点
for(auto j:col){
if(matrix[i][j]==target)return true;
}
}
return false;
}
};
结果

并非高效。
思路二
由于每一行和每一列都是升序的,那么我们需要找出一个起始点,让它的大体移动方向是有区分度的,具体来说就是如下:
左上角:往右往下移动,martix值都变大,无法区分,不可用
右上角:往左martix变小,往下martix变大,可区分,可用
左下角:往右martix变大,往上martix变小,可区分,可用
右下角:往左往上移动,martix都变小,不可区分,不可用
那么我们可以选择右上角向左或向下移动,当matrix[i][j]大于target,由于此时向左或向上是变小,但我们就是从上面下来的,所以此时向左移动或许能找到target,同理,当matrix[i][j]小于target时,该向下。选左下角同理。代码选择从右上角开始。
代码
cpp
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int m = matrix.size();//行
int n = matrix[0].size();//列
if(matrix[0][0]>target||matrix[m-1][n-1]<target){//如果数组最小的数都比target大或者最大的数都比target小,那么直接返回假
return false;
}
int col = n-1,line = 0;//从右上角开始
while(line<=m-1&&col>=0){
if(matrix[line][col]>target)col--;
else if(matrix[line][col]<target)line++;
else return true;
}
return false;
}
};
结果
