题目描述
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
解题思路一
方法非常简单,就是简单的遍历二维数组。这个方法有一个很明显的缺陷,它没有利用题目中“有序”这个条件,如果采用这种方法会发生超时的问题。
解题思路二
针对上一个方法,我们非常容易就想到的一种改进方法就是“折半查找”,对每一行实施折半查找算法,这样时间复杂度就由原来的O(n^2)变为O(nlogn)。
public class Solution {
public boolean Find(int target, int [][] array){
// 判空
if(array==null){
return false;
}
// 判空并获得行宽
int rowLength = array.length;
if(rowLength<1){
return false;
}
// 判空并获得列长
int columnLength = array[0].length;
if(columnLength<1){
return false;
}
boolean isFind = false;
for(int i = 0;i < rowLength;i++){
// 对二维数组的每一行调用折半查找算法
isFind = findByRow(target, array[i]);
if(isFind){
return isFind;
}
}
return false;
}
/**
* 采用折半查找,查找一行
* @param array
* @return
*/
public boolean findByRow(int target, int [] array){
int arrayLength = array.length;
if(arrayLength<1) return false;
return findByRow(target, 0, arrayLength - 1 , array);
}
public boolean findByRow(int target, int start, int end, int [] array){
// 递归的终止条件
if(start>end)return false;
// 除法建议采用右移一位
int mid = (start+end)>>1;
if(target == array[mid]){
return true;
}
if(array[mid]>target){
return findByRow(target, start, mid - 1, array);
}
else {
return findByRow(target, mid + 1, end, array);
}
}
}
解题思路三
其实我们发现,解题思路二只利用了条件“从左到右递增的顺序排序”,而没有利用“从上到下递增的顺序排序”条件,可见还有改进的空间。
通过仔细思考可以发现,矩阵右上角的值array[0][j]比较特殊,它(同一行)左边的值都比它小,它(同一列)的值都比它大。如果target>array[0][j],则target只有可能在第j列中。
public class Solution {
public boolean Find(int target, int [][] array){
// 判空
if(array==null){
return false;
}
// 判空并获得行数
int rowCount = array.length;
if(rowCount<1){
return false;
}
// 判空并获得列数
int columnCount = array[0].length;
if(columnCount<1){
return false;
}
for(int j = columnCount-1 ; j >=0 ; j-- ){
if(array[0][j]==target)return true;
if(array[0][j] < target){
for(int i = 0 ; i< rowCount; i++){
if(array[i][j]==target)return true;
}
}
}
return false;
}
}