题目解析
题目描述
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
}
};
题目解析
分析题意
就是说,有一个行递增,列也递增的矩阵,在里面找一个target
思路
既然是有序数组,那我们就要好好利用它的单调性,比如说二分之类的
在m x n矩阵 matrix中我们可以发现一个性质:对于每个子矩阵右上角的数x,x左边的数都小于等于x,x下边的数都大于x,如下图所示:
因此我们可以从整个矩阵的右上角开始枚举,假设当前枚举的数是 x:
- 如果 x 等于target,则说明我们找到了目标值,返回true;
- 如果 x小于target,则 x左边的数一定都小于target,我们可以直接排除当前一整行的数;
- 如果 x 大于target,则 x 下边的数一定都大于target,我们可以直接排除当前一整列的数;
排除一整行就是让枚举的点的横坐标加一,排除一整列就是让纵坐标减一。当我们排除完整个矩阵后仍没有找到目标值时,就说明目标值不存在,返回false。
具体过程如下:
- 1、初始化i = 0, j = matrix[0].size() - 1。
- 2、如果matrix[i][j] == target,返回true。
- 3、如果matrix[i][j] < target,i++,排除一行。
- 4、如果matrix[i][j] > target,j–,排除一列。
- 5、如果出界了还未找到target,则返回false。
思路二
我们可以将二维矩阵抽象成【以右上角为根的BST】
那么我们可以从根(右上角)开始搜索,如果当前节点不等于目标值,可以按照树的搜索顺序进行:
- 当前节点[大于]目标值,搜索当前节点的[左子树],也就是当前矩阵位置的「左方格子」,即j–
- 当前节点「小于」目标值,搜索当前节点的「右子树」,也就是当前矩阵位置的「下方格子」,即i++
实现
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if(matrix.empty()){
return false;
}
int m = matrix.size(), n = matrix[0].size();
int i = 0, j = n - 1;
// 只要没有越界就继续判断
while (i >= 0 && i < m && j >= 0 && j < n){
int curr = matrix[i][j];
if(curr > target){
--j;
}else if(curr < target){
++i;
}else{
return true;
}
}
return false;
}
};
类似题目
题目 | 思路 |
---|---|
leetcode:74. 搜索二维矩阵 Search a 2D Matrix | 二维转一维 |
leetcode:240. 搜索二维矩阵 IISearch a 2D Matrix | 二分 |