题目描述
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路:首先这个有两种解题的思路,第一种就是:因为每一行都是有序的。然后我们可以一行用一个折半查找进行(时间复杂度是log2(n)),然后设置一个外层循环遍历每一行。
代码:
public static boolean find(int target, int[][] array){
int rows = array.length;
for(int i = 0; i < rows; i ++){
int start = 0;
int end = array[0].length-1;
while(start <= end){
int mid = (start+end)>>>1;
if(target == array[i][mid]){
return true;
}else if(target > array[i][mid]){
start = mid + 1;
}else{
end = mid - 1;
}
}
}
return false;
}
第二种解题思路则是:从最后一行的最左下角开始,情况一:如果最后一行的第一个比这个target大,那这个时候查找的范围就将最后一行舍去,因为每一行都是有序的,最后一行第一个都比这个大,那么最后一行的其他的肯定也比这个target大。情况二:如果最后一行的第一个数比target这个数小,那么此时需要比较的就是最后一行的其他数。这个时候列下标往右移动,如果之后比较的值笔这个target大,这个时候就需要行下标向上移动。此时之前的列就不用比较了。(比如当前行的第一个数比target小,那么在前面所有行中的第一个数都要比这个target小。所以此时当前列右移。下一次循环如果第二个数比target小,那么此时就是rows--,但是列不变,前面的列都已经排除了)
public static boolean find(int target, int[][] array){
int rows = array.length-1;
int cols = array[0].length-1;
int currCol = 0;
while(rows >= 0 && currCol <= cols){
if(target < array[rows][currCol]){//这里是当最后一行的第一个比这个查询的值大,那么最后一行肯定都比这个需要查询的值大,所以行--
rows --;
}else if(target > array[rows][currCol]){
//如果这个target笔这个查询的值大,那么这个值只能在最后一行的右边,或者是前面行的当前列的右边列。
//比如当前行的第一个数比target小,那么在前面所有行中的第一个数都要比这个target小。所以此时当前列
//右移。下一次循环如果第二个数比target小,那么此时就是rows--,但是列不变,前面的列都已经排除了。
currCol ++;
}else{
return true;
}
}
return false;
}