在一个 n * m
的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例:
现有矩阵 matrix 如下:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
方法一:暴力查找法
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
if(matrix==null||matrix.length==0||matrix[0].length==0){
return false;
}
int rows=matrix.length;
int columns=matrix[0].length;
for(int n=0;n<rows;n++){
for(int m=0;m<columns;m++){
if(matrix[n][m]==target){
return true;
}
}
}
return false;
}
}
复杂度分析
时间复杂度:O(nm)。二维数组中的每个元素都被遍历,因此时间复杂度为二维数组的大小。 空间复杂度:O(1)。
方法二:线性查找法
解析:
1. 如果从左上角开始找,那么如果当前数比目标值小的话,向下走或者向右走都可以让数变大,方向就不能确定
2. 所以应该找从两个方向走一个是变大的一个变小的位置作为起始位置,比如右上角和左下角
3. 以右上角为例,如果当前数比目标值大,往左走;如果当前数比目标值小,往下走
4. 如果找到就返回true
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
if(matrix==null||matrix.length==0||matrix[0].length==0){
return false;
}
int rows=matrix.length;
int columns=matrix[0].length;
//右上角的下标
int n=0;
int m=columns-1;
while(n<rows&&m>=0){
if(matrix[n][m]==target){
return true;
}
if(matrix[n][m]<target){
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 rows=matrix.length;
int columns=matrix[0].length;
for(int n=0;n<rows;n++){
int right=0;
int left=columns-1;
while(right<=left){
int mid=(right+left)/2;
if(matrix[n][mid]==target){
return true;
}
if(matrix[n][mid]>target){
left=mid-1;
}else{
right=mid+1;
}
}
}
return false;
}
}