算法(一)

从今天起,坚持每天做3道算法题,争取在半个月内将剑指offer的题刷完。

剑指offer第一题:
二维数组的查找。

从一个矩阵中找出一个数来,这个矩阵的行是递增的,列是递增的。

第一版代码:

	package com.study;
	
	public class suanfa1 {
	
		private static int[][] matrix = { { 1, 2, 8, 9 }, { 2, 4, 9, 2 },
				{ 4, 7, 10, 13 }};
	
		public static boolean findNumber(int[][] matrix, int num) {
			int i = 0;
	
			for (int j = 0; j < matrix[i].length; j++) {
	
				if (matrix[i][j] > num) {
					j--;
					for (i = 0; i < matrix[j].length; i++) {
	
						if (matrix[i][j] > num) {
							return false;
						} 
						else if (matrix[i][j] == num) {
							return true;
						}
					}
				} else if (matrix[i][j] == num)
					return true;
			}
			
			return false;
		}
	
		public static void main(String[] args) {
			System.out.println(findNumber(matrix, 5));
		}
	}

虽然做出来了,但是并非最优。

第二版

package com.study;

public class suanfa1 {

	private static int[][] matrix = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 },
			{ 4, 7, 10, 13 } };

	public static boolean findNumber(int[][] matrix, int num) {
		if(matrix != null) {
			int j = matrix[0].length - 1; //游标 j 指向矩阵的最大列数
			int i = 0;           		  //游标i指向矩阵的初始行
			
			/*
			 * 如果就在这一列
			 * */
			while(i <= matrix.length &&  matrix[i][j] < num) { 
				i++;				
			}
			
			if(matrix[i][j] == num)
				return true;
			
			/**
			 * 如果不在这一列的话
			 * */
			
			
			/*以下确定矩阵的范围*/
			while(matrix[i][j] > num) 
				j--;
			
			while(matrix[i][j] < num)
				i++;
			
			
			while(i < matrix.length-1 && j >= 0) {
				if(matrix[i][j] > num) 
					j--;
				if(matrix[i][j] < num)
					i++;
				if(matrix[i][j] == num)
					return true;
			}
		}		
		
		return false;
	}

	public static void main(String[] args) {
		System.out.println(findNumber(matrix, 13));
	}
}

思路:

锁定列:

先把数锁定到最后一列的第一个数,因为这样就可以将整个二维数组分成两部分,一部分是大于这个数的,另一部分是小于这个数的,如果这个数大于所要找的数,则查找范围锁定到前一部分,然后再按照这种方法去找;如果小于所要找的数,则肯定在这一列。

锁定行:

锁定列之后,路线沿着此列往下找,因为此列上的元素都是相应行上最大的数。

最后只剩一个小矩阵,此时在分列或行查找,就easy多了。

你可能感兴趣的:(算法)