原题
题解
方法一
暴力搜索
本思路Java代码示例:
/*暴力
*@v7fgg
*执行用时:21 ms, 在所有 Java 提交中击败了6.0%的用户
*内存消耗:45.3 MB, 在所有 Java 提交中击败了17.86%的用户
*2020年6月20日 15:22
*/
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
for(int i=0;i<matrix.length;i++){
for(int j=0;j<matrix[0].length;j++){
if(matrix[i][j]==target){
return true;
}
}
}
return false;
}
}
方法二
逐行实用二分法。
这只需要下遍历每行的首个和最后一个数字,看target在不在范围内,不在则继续搜索。如若搜到某一行可能包含target,则进行二分搜索。
本思路java代码示例:
/*
*@v7fgg
*执行用时:7 ms, 在所有 Java 提交中击败了60.33%的用户
*内存消耗:45.7 MB, 在所有 Java 提交中击败了7.14%的用户
*2020年6月20日 16:04
*/
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix.length>0&&matrix[0].length>0){
for(int i=0;i<matrix.length;i++){
//如果搜到某行第一个数都比target大,那么接下来就都不可能存在了
if(matrix[i][0]>target){break;}
//某行最大的数比target小,需要继续搜索下一行
if(matrix[i][matrix[0].length-1]<target){continue;}
if(erfen(matrix[i],target)){return true;}
}
}
return false;
}
public boolean erfen(int a[],int target){
//二分法判断某升序数组是否含有target
int left=0;
int right=a.length-1;
while(left<=right){
//注意是left<=right
int mid=(left+right)/2;
if(a[mid]>target){right=mid-1;}
else if(a[mid]<target){left=mid+1;}
//增加这个判断if(left==right)
else if(left==right){return a[mid]==target;}
else{return true;}
}
return false;
}
}
方法三
设定一个指针,从右上角开始,若指针出大于target,指针左移,若小于,指针下移,直到找到或者出界。
本思路java代码示例:
/*
*@v7fgg
*执行用时:6 ms, 在所有 Java 提交中击败了99.79%的用户
*内存消耗:45.6 MB, 在所有 Java 提交中击败了14.29%的用户
*2020年6月20日 17:48
*/
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix.length>0&&matrix[0].length>0){
int m=0;
int n=matrix[0].length-1;
while(m<matrix.length&&n>=0){
if(matrix[m][n]>target){n--;}
else if(matrix[m][n]<target){m++;}
else{return true;}
}
}
return false;
}
}