剑指offer面试题4:二维数组中的查找-Java实现

题目:不写了
描述:省略

我的思路:递归实现的二分法查找。
记录数组的长和宽,用二分查找找到位于中间的那个元素,以这个元素为中心,根据他的横纵坐标轴可以把原二位数组划分为四份。
其中,左上角的二维数组中的任意元素,必定小于等于该元素,右下角的二维数组中的任意元素必定大于该元素。
因此,只要我们在每一次寻找中间元素的过程时,记录下必定大于目标元素,和小于目标元素的横纵坐标的上界与下界。将左上角和右下角的二维数组排除,对左下角和右上角的二维数组迭代这一过程,就可确定数组中是否存在该元素。

该方法,每一次划分二维数组的过程的时间复杂度是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;
	}

算是两种方法吧,觉得自己的方法,用二分法是快一些,但是递归要为方法开辟很多空间。

猜你喜欢

转载自blog.csdn.net/qq_40473204/article/details/107721970