思路:
方法一:暴力法
方法二:线性查找,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序,这句话没有被暴力法充分利用上。由于该特性,当target<当前数值时,列往左搜寻;当target>当前数值时,行向下搜寻
方法三:二分查找,二分查找只能是一维的,所以是要对所有行进行二分查找
代码:
方法一:
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
//注意顺序
if(matrix==null || matrix.length==0||matrix[0].length==0){
return false;
}
int n=matrix.length;
int m=matrix[0].length;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(matrix[i][j]==target){
return true;
}
}
}
return false;
}
}
方法二:
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
if(matrix==null||matrix.length==0||matrix[0].length==0){
return false;
}
int row=matrix.length;
int col=matrix[0].length;
int m=0,n=col-1;
while(m<row && n>=0){
int num=matrix[m][n];
if(num==target){
return true;
}
else if(target<num){
n--;
}
else{
m++;
}
}
return false;
}
}
方法三:
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
if(matrix==null||matrix.length==0||matrix[0].length==0){
return false;
}
int row=matrix.length;
int col=matrix[0].length;
for(int i=0;i<row;i++){
boolean flag=biSearch(matrix[i],target);
if(flag){
return true;
}
}
return false;
}
private boolean biSearch(
int[] mat,
int target
){
int left=0,right=mat.length,mid=0;
while(left<right){
if(mat[mid]==target){
return true;
}
mid=left+(right-left)/2;
if(target<mat[mid]){
right=mid;
}
else if(target>mat[mid]){
left=mid+1;
}
}
return false;
}
}
分解:
1)在判空时,要注意写的顺序,matrix.length==0要在matrix[0].length==0的左边写
matrix.length==0||matrix[0].length==0
2)方法二,while循环的条件是:不超过边界(m<row && n>=0),本题解从右上角开始搜寻
3)方法三,对每一行进行二分查找
for(int i=0;i<row;i++){
boolean flag=biSearch(matrix[i],target);
if(flag){
return true;
}
}
时间、空间复杂度分析:
暴力法:
i)时间复杂度:O(m*n) 每轮每行都遍历m次,每列都遍历n次
ii)空间复杂度:O(1) 没有额外开空间
线性查找:
i)时间复杂度:O(m+n) 全过程中行只遍历m次,列只遍历n次
ii)空间复杂度:O(1) 没有额外开空间
二分查找:
i)时间复杂度:O(m*log(n)) 每轮每列都遍历log(n)次,遍历了m次
ii)空间复杂度:O(1) 没有额外开空间
总结:最优解是线性查找,时间复杂度为O(m+n)