题目
编写一个高效的算法来判断 m x n
矩阵中,是否存在一个目标值。该矩阵具有如下特性:
- 每行中的整数从左到右按升序排列。
- 每行的第一个整数大于前一行的最后一个整数。
示例 1:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true
示例 2:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
输出:false
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 100
-10^4 <= matrix[i][j], target <= 10^4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-a-2d-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路1
由于矩阵整体是升序排列,可以先确定目标值所在的行,再遍历该行,即可得到是否存在目标值。
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int m=matrix.size(),n=matrix[0].size();
if(target>matrix[m-1][n-1]) return false;
int row;
for(int i=0;i<m-1;i++) {
if(matrix[i][0]<=target && matrix[i+1][0]>target) {
row=i;
break;
}
}
for(int i=0;i<n;i++) {
if(matrix[row][i]==target) {
return true;
}
}
return false;
}
};
思路2
暴力法虽好,却不是正道。
采用2次二分搜索,第一次二分找到所在的行,第二次二分找到所在的列,二分的条件需要多加注意。
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int m=matrix.size(),n=matrix[0].size();
if(target>matrix[m-1][n-1]) return false;
int rleft=0,rright=m-1,row=0;
while(rleft<=rright) {
int mid=(rright-rleft)/2+rleft;
if(matrix[mid][0]==target) {
return true;
} else if(matrix[mid][0]<target){
rleft=mid+1;
row=mid;
} else {
rright=mid-1;
}
}
int cleft=0,cright=n-1;
while(cleft<=cright) {
int mid=(cright-cleft)/2+cleft;
if(matrix[row][mid]==target) {
return true;
} else if(matrix[row][mid]<target) {
cleft=mid+1;
} else {
cright=mid-1;
}
}
return false;
}
};
思路3
看了dalao的题解才知道可以从矩阵的右上角或者左下角开始遍历寻找:https://leetcode-cn.com/problems/search-a-2d-matrix/solution/fu-xue-ming-zhu-liu-chong-fang-fa-bang-n-e20z/
从矩阵的右上角开始遍历:
- 如果要搜索的 target 比当前元素大,那么让行增加;
- 如果要搜索的 target 比当前元素小,那么让列减小;
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int m=matrix.size(),n=matrix[0].size();
if(target>matrix[m-1][n-1]) return false;
int row=0,col=n-1;
while(row<m&&col>=0) {
if(matrix[row][col]>target) {
col--;
} else if(matrix[row][col]<target) {
row++;
} else {
return true;
}
}
return false;
}
};