算法(一)
从今天起,坚持每天做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多了。