题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
解题思路
解法一:我们可以去遍历这个二维数组,但是呢,如果在面试过程中的话,这种做法是很不可取的。原因是因为时间复杂度太高了。达到了O(n的平方)。而且这种方法也没有任何技巧和方法,不建议这样做。
代码:
public boolean FindS(int target, int [][] array) {
for(int i = 0;i < array.length;i++){
for(int j = 0 ; j < array[i].length; j++){
if(array[i][j] == target){
return true;
}
}
}
return false;
}
解法二:我们在解法一的基础上可以稍作改进,让它的时间复杂度变低,那么怎么做呢,相信大部分已经有思路了。对的,对每一行或者每一列采用二分查找。时间复杂度是不是变为O(nlog(n))了。
代码:
public boolean FindX(int target, int [][] array){
for(int row = 0; row < array.length; row++){
//对每一行二分查找
int low = 0;
int high = array[row].length-1;
while(low <= high){
//加法容易溢出,改为减法
int mid= high - (high - low ) / 2;
if( target == array[row][mid])
return true;
else if (target < array[row][mid])
high = mid - 1 ;
else
low = mid + 1;
}
}
return false;
}
解法三:我们观察题目描述:每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。有没有想到什么,任性一点,我随便进来一个数,在这个二维矩阵里面有什么地位,地位当然比他前面一个数大,比他上面一个数大,地位也不低嘛。所以我们可以从二维数组的左下角或者右上角选择一个元素a[row][col]与target进行比较。
当target小于元素a[row][col]时,那么target必定在元素a所在行的左边,
即col–;
当target大于元素a[row][col]时,那么target必定在元素a所在列的下边,
即row++;
如果是等于呢,那么恭喜你。
代码:
public boolean FindXPlus(int target, int [][] array) {
//从右上角开始
int col = array[0].length - 1;
for(int row = 0 ;row < array.length && col>=0 ; ){
if(target == array[row][col])
return true;
else if(target < array[row][col])
col--;
else
row++;
}
return false;
}