剑指Offer(一):二维数组中的查找
题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
题目中的数组大概就是这样:
- 1 2 3 4
- 5 6 7 8
- 9 10 11 12
解题思路:
方法一:暴力法
优点:易于理解
直接遍历获取进行比较
不过多讲解了直接放代码
public class Solution {
public boolean Find(int target, int [][] array) {
for(int i=0;i<array.length;i++){
for(int j=0;j<array[0].length;j++){
if(array[i][j]==target){
return true;
}
}
}
return false;
}
}
运行时间:221ms
占用内存:17368k
比较数字:8
- 1 2 3 4
- 5 6 7 8
- 9 10 11 12
-比较次数:8
时间复杂度O(n*m)
缺点很明显,时间复杂度太高,消耗的资源也很大
方法二:左下右上排除法
优点:节省空间,一次排除一行或一列
讲解:
比较数字:8
- 1 2 3 4
- 5 6 7 8
- 9 10 11 12
如图所示的数组我们可以发现左下或右上的数字都有一个明显的特点
我们先按左下来讲,左下的数字都是每一行中最小的,并且是每一列中最大的。
所以我们可以利用这一个特点去简化比较的流程。
如果我们用左下数字进行比较。
很明显4比5要小,但是3是这一列中最大的 所以说我们可以直接剔除掉3所在的一整列,我们的数组就变成了这样:
比较数字:8 - 2 3 4
- 6 7 8
- 10 11 12
继续比较8与10,很明显8比10小,因为10是这一行最小的,所以说10所在的一行都比8大,我们直接剔除掉10所在的一整行:
比较数字:8 - 2 3 4
- 6 7 8
再进行两次我们就可以得到结果
比较次数:4
代码如下:
public class Solution {
public boolean Find(int target, int [][] array) {
int cols =array.length-1;//最大列数
int rows = 0;//行数为0
//获取左下角数组的位置坐标
while(cols>=0&&rows<array[0].length){
if(array[cols][rows]>target){
cols--;
}else if(array[cols][rows]<target){
rows++;
}else{
return true;
}
}
return false;
}
}