在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
1. 暴力法
直接遍历二维数组,如果存在就返回true。时间复杂度O(n2)。
//暴力法
public boolean Find1(int target, int[][] array) {
for (int[] arr : array) {
for (int a : arr) {
if (target == a) {
return true;
}
}
}
return false;
}
测试结果:
运行时间:181ms 占用内存:17444k
2. 从左下角查找
由于序列具有以下性质:
- 一行都按照从左到右递增的顺序排序
- 每一列都按照从上到下递增的顺序排序
对左下角m来说,是该列最大值,是该行最小值
- 若m==target,返回true
- 若m>target,则row–
- 若m<target,则col++
时间复杂度为:O(rows+cols)
//从左下角比较
public boolean Find2(int target,int[][] array){
int rows=array.length;
if(rows==0)return false;
int cols=array[0].length;
int row=rows-1;
int col=0;
while(row>=0&&col<cols){
if(array[row][col]>target)row--;
else if(array[row][col]<target)col++;
else return true;
}
return false;
}
测试结果:
运行时间:165ms 占用内存:18488k
3.折半查找
从最后一行向上比较确定在那一行,对此行使用折半查找。对m行n列矩阵数组,时间复杂度为O(m+log2n)
public boolean Find3(int target,int[][] array) {
int rows=array.length;
System.out.println(rows);
if(rows==0)return false;
int cols=array[0].length;
if(cols==0)return false;
for(int row=rows-1;row>=0;row--){
if(target>=array[row][0]&&target<=array[row][cols-1]){
if(array[row][0]==target)return true;
if(array[row][cols-1]==target)return true;
int left=0,right=cols-1;
while (left<right){
int mid=left+(right-left)/2;
if(array[row][mid]==target)return true;
if(array[row][mid]>target)right=mid-1;
if(array[row][mid]<target)left=mid+1;
}
break; //查找终止
}
}
return false;
}
测试结果:
运行时间:146ms 占用内存:18064k