剑指offer第二版面试题4:二维数组中的查找(java)
面试题4:二维数组中的查找
题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否函数该整数。
当然最简单的两层循环是可以实现的,但是这样没有意义,我的第一个反应就是双层循环的稍微优化一点点。
-
main函数
public static void main(String[] args) { int[][] arr = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}}; System.out.println(findnumber(arr,14));; }
-
手写
public static boolean findnumber(int[][] arr,int number){
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
if(arr[i][j]==number){
return true;
}else {
if (arr[i][j]>number){
break;
}
}
}
}
return false;
}
就是从左上方开始,如果发现下一个元素比number大,那么直接进入下一行去比较。
缺点:O2的时间复杂度
-
答案
从右上角或者左下角开始进行查找,只要比最右侧列的第一个元素小,则最右侧一整列的元素都可舍弃,进行下一次循环,如果比最右侧列的第一个元素大,则舍弃掉这一行,以此类推,直到找到该元素。
public static boolean findnumber(int[][] arr,int number){
int rows = 0; //行数
int coloumns = arr[0].length-1; //列数
while (rows<arr.length && coloumns>=0){
if(arr[rows][coloumns]==number){
return true;
}else if(arr[rows][coloumns]>number){
coloumns--;
}else if(arr[rows][coloumns]<number){
rows++;
}
}
return false;
}
分析:本题的关键就在于,发现右上角这一个特殊的点,左上是比自己小的,右下是比自己大的。那么只要找到角即可解决问题。