学习剑指offer第三题时,想着不看答案,自己先写一种实现,看了参考答案的思路,自己用标准答案的另外一种想法,结合了分治思想,搞了一天,才搞出一版代码,感觉很happy,发个原创,供大家参考,也为了自己以后查看方便。欢迎讨论,转载请注明出处,谢谢! public class Test03 { /** * 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。 * 请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 * * @param matrix 待查找的数组 * @param number 要查找的数 * @return 查找结果,true找到,false没有找到 */ // 自解思想:从主对角线array[0][0]、array[1][1]、...、array[n][n]这条线去找 // 找到array[i][i]比number小,array[i+1][i+1]比number大 // 则查找目标不在array[0][0]到array[i][i]的正方形区域内 // 也不在array[i+1][i+1]到array[x-1][y-1]的长方形区域内 // 左上和右下区域被剔除,剩余左下和右上两块,用分治法查找这两块区域 // 可能会完全剔除左边,或者完全剔除右边,分治剩余部分即可 public static boolean find(int[][] matrix, int number) { int x = matrix.length; int y = matrix[0].length; return findInMatrix(matrix, number, 0, 0, x-1, y-1); } // 用原数组,要找的数字,寻找的区域(用左上下标和右下下标表示) public static boolean findInMatrix(int[][] matrix, int number, int x1, int y1, int x2, int y2) { System.out.println("search area:("+(x1+1)+", "+(y1+1)+"), ("+(x2+1)+", "+(y2+1)+")"); if (matrix[x1][y1] > number) { return false; } if (matrix[x2][y2] < number) { return false; } // 所有的return都是递归出口 if (x1 == x2) { for (int j=y1; j<=y2; j++) { if (matrix[x1][j] == number) { System.out.println("find: ("+(x1+1)+", "+(j+1)+")"); return true; } } return false; } if (y1 == y2) { for (int i=x1; i<=x2; i++) { if (matrix[i][y1] == number) { System.out.println("find: ("+(i+1)+", "+(y1+1)+")"); return true; } } return false; } int lessI = 0, lessJ = 0; //从正对角线开始找,记录行标 for (int i = x1, j = y1; i <= x2 && j <= y2; i++, j++) { if (matrix[i][j] == number) { System.out.println("find: ("+(i+1)+", "+(j+1)+")"); return true; } else if (matrix[i][j] < number) { lessI = i; lessJ = j; } else { break; } } int iIndex = lessI+1; int jIndex = lessJ+1; if (iIndex <= x2) { //还存在左下区域 if (findInMatrix(matrix, number, iIndex, y1, x2, lessJ)) { return true; } } if (jIndex <= y2) { //还存在右上区域 if (findInMatrix(matrix, number, x1, jIndex, lessI, y2)) { return true; } } return false; } public static void main(String[] args) { int[][] array = new int[][]{ { 1, 3, 5, 7, 9, 11, 13, 15, 17}, { 2, 6, 6, 8, 10, 12, 14, 16, 18}, { 3, 9, 11, 13, 15, 17, 19, 21, 23}, { 4, 10, 12, 14, 16, 18, 20, 22, 24}, { 5, 13, 15, 21, 41, 61, 81, 83, 101}, { 7, 16, 18, 24, 44, 64, 84, 94, 104}, { 9, 19, 25, 35, 55, 75, 95, 105, 115}, { 10, 20, 30, 40, 60, 80, 100, 110, 120} }; System.out.println(find(array, 5)); } }
剑指Offer学习 【面试题3 :二维数组中的查找】 主对角线分治解法
最新推荐文章于 2021-08-07 13:29:28 发布