题目:不写了
描述:省略
我的思路:递归实现的二分法查找。
记录数组的长和宽,用二分查找找到位于中间的那个元素,以这个元素为中心,根据他的横纵坐标轴可以把原二位数组划分为四份。
其中,左上角的二维数组中的任意元素,必定小于等于该元素,右下角的二维数组中的任意元素必定大于该元素。
因此,只要我们在每一次寻找中间元素的过程时,记录下必定大于目标元素,和小于目标元素的横纵坐标的上界与下界。将左上角和右下角的二维数组排除,对左下角和右上角的二维数组迭代这一过程,就可确定数组中是否存在该元素。
该方法,每一次划分二维数组的过程的时间复杂度是log
(n),而每一次排除剩余元素的一半,因此总共会进行logn次,也就是O((logn)的平方)的时间复杂度
public class Test4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int width = 0;
int height = 0;
width = input.nextInt();
height = input.nextInt();
int findInt = input.nextInt();
ArrayList<ArrayList<Integer>> dimen2 = new ArrayList<ArrayList<Integer>>(height);
for(int count = 0; count < height ; count++) {
ArrayList<Integer> temp = new ArrayList<Integer>(width);
for(int count_inner = 0;count_inner < width; count_inner++) {
temp.add(input.nextInt());
}
dimen2.add(temp);
}
show(width,height,dimen2);
boolean result = false;
if(dimen2.get(width-1).get(height-1) < findInt) {
result = false;
}else {
result = binary_find(0,width,0,height,dimen2,findInt);
}
if(result == true) {
System.out.println("ok");
}else {
System.out.println("not yet");
}
}
public static boolean binary_find(int least_width,int biggest_width,int least_height,int biggest_height,ArrayList<ArrayList<Integer>> dimen2,int findInt) {
int mid_width = (biggest_width - least_width)/2;
int mid_height = (biggest_height - least_height)/2;
int cash_bw = biggest_width;
int cash_bh = biggest_height;
int cash_lw = least_width;
int cash_lh = least_height;
while(true) {
if(dimen2.get(mid_width).get(mid_height) == findInt) {
return true;
}else if(dimen2.get(mid_width).get(mid_height) < findInt) {
least_width = mid_width;
least_height = mid_height;
mid_width = (least_width + biggest_width)/2;
mid_height = (least_height + biggest_height)/2;
}else if(dimen2.get(mid_width).get(mid_height) > findInt) {
biggest_width = mid_width;
biggest_height = mid_height;
mid_width = (least_width + biggest_width)/2;
mid_height = (least_height + biggest_height)/2;
}
if(biggest_width - least_width <= 1) {
break;
}
}
if(least_width + 1 != cash_lw && biggest_height != cash_bh) {
binary_find(least_width + 1,cash_bw,cash_lh,biggest_height,dimen2,findInt);
}
if(biggest_width != cash_bw && least_height + 1 != cash_lh) {
binary_find(cash_lw,biggest_width,least_height + 1,cash_bh,dimen2,findInt);
}
return false;
}
public static void show(int width,int height,ArrayList<ArrayList<Integer>> dimen2) {
for(int count = 0; count < height ; count++) {
for(int count_inner = 0;count_inner < width; count_inner++) {
System.out.print(dimen2.get(count).get(count_inner)+" ");
}
System.out.println();
}
}
}
作者的方法是从右上角第一个元素开始,进行判断,若比要寻找的元素大,则将坐标左移,若比要寻找的元素小,则将坐标下移,直至遍历完成,时间复杂度O(n+m)
public static boolean authorMethod(int width,int height,ArrayList<ArrayList<Integer>> dimen2,int findInt) {
int start_width = width-1;
int start_height = 0;
while(start_width > 0 && start_height < height) {
System.out.println(dimen2.get(start_height).get(start_width));
if(dimen2.get(start_height).get(start_width) < findInt) {
start_height++;
}else if(dimen2.get(start_height).get(start_width) > findInt) {
start_width--;
}else {
return true;
}
}
return false;
}
算是两种方法吧,觉得自己的方法,用二分法是快一些,但是递归要为方法开辟很多空间。