题目:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
题目来源:牛客网
首先看看什么是二维数组:下面的数组就是一个int[3][5]的数组。
我一看到,就想的是直接遍历比较。(果然还是太菜了啊。)然后又想到昨天面试时,字节跳动的面试官小姐姐说的:“你多想想其他的情况。”。好吧我想了一下,递增序列,折半查找。嗯,加上后牛客的测试时间更加长了,我懵了。没道理啊,一个时间复杂度是n[n],一个是n[log2n]。
上代码:
//暴力的顺序查找,双重for循环,牛客测试:运行时间:149ms,占用内存:17420k
public static boolean Find(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;
}
//依旧是暴力的解决问题:foreach循环,n^n。牛客网上的测试时间是:运行时间:149ms,占用内存:17552k
public static boolean Find2(int target,int[][] array){
for(int[] arr : array){
for(int i : arr){
if(target == i){
return true;
}
}
}
return false;
}
//换个方式解决,由于每一行是递增序列,因此对每一行进行折半查找.时间复杂度为n^log2n。牛客:运行时间:186ms,占用内存:17408k
public static boolean Find3(int target,int[][] array){
for(int i = 0;i< array.length;i++){
int mid;
int low = 0;
int high = array[i].length -1;
while (low <= high){
mid = (low+high)/2;
if(target < array[i][mid]){
high = mid-1;
}else if(target >array[i][mid]){
low = mid+1;
}else {
//相等的时候
return true;
}
}
}
return false;
}
后面去看了牛客网的网友们分享的,其中有一个也是在里面每列加上一个折半查找,然后还提供了一种思路。自己看了想了下,确实更好,但是不是自己的想法,因此就放传送门吧:牛客网