今天看到一道题:
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
拿到题脑子热,两层循环能解决,直接上代码 :
public class Solution {
public boolean Find(int target, int [][] array) {
int i,j,k,m;
if (array==null||array.length==0||(array.length==1&&array[0].length==0))
return false;
for (i=0;i<array.length;i++){
if (target==array[i][0])
return true;
if(i==array.length-1){
for (k=0;k<array[i].length;k++){
if(target==array[i][k])
return true;
else return false;
}
}
if(target>array[i][0]& target<=array[i+1][0])
for (j=0;j<array[i].length;j++){
if (target==array[i][j])
return true;
}
for (m=0;m<array[i].length;m++){
if (target==array[i+1][m])
return true;
}
}
return false;
}
}
但是写完了之后发现,这样来 解决这个问题 ,时间复杂度达到了n^2,然后就想到 了,如果用二分查找来解决应该会减小时间复杂度 ,心血来潮,想试试看自己能 写出二分查找算法 不 。
接着就试试用“数组来”数据类型看能不能实现,毕竟很菜,写的肯定不是最简单的 ,但是 花了很长时间终于写出来了。
这里只把 算法的查找功能写出来了,这道题的具体解决没有实现,因为根据这道题,可以用循环把每行第一个元素放进 一个数组,然后调用二分 函数,这里可以先修改下二分函数,让返回i的值,这样就能定位到 具体哪一行,然后找到这行 再调用二分函数 就ok,代码没有很规范,希望谅解,菜鸟摸爬滚打。
public class Test2 {
static int []array={1,3,5,7,9,11,13,15,18,33,34,45,55,66,78,85,95};
public static void main(String[] args) {
boolean b;
b=function(array, 78);
System.out.println(b);
}
public static boolean function(int[]array,int target){
int m=0,n=0;
int i=array.length/2;//初值
int k=(array.length-i)/2;//折半后确定i的位置(这里赋初始值)
if (target > array[array.length-1] || target < array[0]){
System.out.println("不好意思,数组里没有哦,嘻嘻~");
return false;
}
if(target==array[0]|target==array[array.length-1])
return true;//判断首尾部
while (true){
if (target==array[i]){
System.out.println("查找到目标,下标为:"+i);
return true;
}
else if (target>array[i]){
i=i+k/2;//大于中间值,索引i增加后半部分的一半
if (i==n)//判断i是否和上一轮相等
return false;
m=i;
}
else {
i=i-k/2;//小于中间值,i减小为前半部的一半
if (i==m)
return false;
n=i;
}
k=k/2;//每次判断完k的范围 缩小一半
if (k==0)//处理边界值,k范围等于1时
k=2;
}
}
}
验证了边界和中间值 还有数组外值,发现都可以返回成功。