《剑指offer》——矩阵中的路径
来源:互联网 发布:iphone清理缓存软件 编辑:程序博客网 时间:2024/06/06 17:55
T:
题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b c e s f c s a d e e 矩阵中包含一条字符串”bccced”的路径,但是矩阵中不包含”abcb”路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
这个题目,还是有点儿bug的,举例都弄错了,”bccced”应改为”bcced”。
这个题目,我第一个想到的方法,就是递归。忽然发现,好多问题,都可以用递归解决。。。
这个代码,也是修改了好几次,总是有很多小bug,总的来说,不算好代码,但也毕竟是自己吭哧吭哧了一个小时搞出来的东西,还是应该贴一下。
code:
package niuke.sward2offer.pathInMatrix; import java.util.ArrayList; /** * T: 矩阵中的路径 * * 题目描述 * 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。 * 路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。 * 如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 * 例如 a b c e s f c s a d e e 矩阵中包含一条字符串"bccced"的路径, * 但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。 * * date: 2015.11.5 * @author SSS * */ public class Solution { public boolean hasPath(char []matrix, int rows, int cols, char[] str) { boolean flag = false; // 将一维数组转变为二维数组,方便处理 char [][]newMatrx = new char[rows][cols]; for (int i = 0; i < matrix.length; i++) { newMatrx[i/cols][i%cols] = matrix[i]; } // 标记位,若已经访问过,那就置为1,否则置为0 int [][]flagMatrix = new int[rows][cols]; for (int i = 0; i < flagMatrix.length; i++) { for (int j = 0; j < flagMatrix[0].length; j++) { flagMatrix[i][j] = 0; } } // 将char型的数组也转变为String,方便计算 String newStr = String.valueOf(str); /** * 对于二维数组中的元素,逐个匹配,即使第一次匹配成功了,也要继续往下匹配, * 以防这一次的不成功,而成功的路径在下一次的匹配上 */ for (int i = 0; i < newMatrx.length; i++) { for (int j = 0; j < newMatrx[0].length; j++) { if (newMatrx[i][j] == str[0]) { flagMatrix[i][j] = 1; if (newStr.length() == 1) { flag = true; } else { flag = this.getResult(newMatrx, flagMatrix, i, j, newStr.substring(1)); } if (flag) { break; } // 如果不匹配,要重新置为0 flagMatrix[i][j] = 0; } } if (flag) { break; } } return flag; } /** * 递归函数:在newMatrix这个二维数组内,当前的位置处在【rows】和【cols】上, * 那就从上下左右一次寻找,寻找该点周围的其他点,是否有和newStr的第一个字母相同的, * 如果有相同的,那就进行下一次的递归;如果不相同,那就返回false. * * 终止条件: * 当前函数中的newStr字符串的长度为1,然后再在该点周围的四个方向上找 * 是否有和该字母相同的,如果相同,那就返回true,否则就返回false * * 方法略笨了些,应该还可以进一步简化 * * @param newMatrix * @param flagMatrix * @param aIndex * @param bIndex * @param newStr * @return */ public boolean getResult(char [][]newMatrix, int [][]flagMatrix, int aIndex, int bIndex, String newStr) { char temp= newStr.charAt(0); if (newStr.length() == 1) { //左 if (bIndex > 0 && flagMatrix[aIndex][bIndex - 1] == 0 && newMatrix[aIndex][bIndex - 1] == temp) { return true; } // 上 if (aIndex > 0 && flagMatrix[aIndex - 1][bIndex] == 0 && newMatrix[aIndex - 1][bIndex] == temp) { return true; } // 右 if (bIndex < (flagMatrix[0].length - 1) && flagMatrix[aIndex][bIndex + 1] == 0 && newMatrix[aIndex][bIndex + 1] == temp) { return true; } // 下 if (aIndex < (flagMatrix.length - 1) && flagMatrix[aIndex + 1][bIndex] == 0 && newMatrix[aIndex + 1][bIndex] == temp) { return true; } return false; } boolean flag = false; if (bIndex > 0 && flagMatrix[aIndex][bIndex - 1] == 0 && newMatrix[aIndex][bIndex - 1] == temp) { flagMatrix[aIndex][bIndex - 1] = 1; flag = this.getResult(newMatrix, flagMatrix, aIndex, bIndex - 1, newStr.substring(1)); } if (aIndex > 0 && flagMatrix[aIndex - 1][bIndex] == 0 && newMatrix[aIndex - 1][bIndex] == temp && flag == false) { flagMatrix[aIndex - 1][bIndex] = 1; flag = this.getResult(newMatrix, flagMatrix, aIndex - 1, bIndex, newStr.substring(1)); } if (bIndex < (flagMatrix[0].length - 1) && flagMatrix[aIndex][bIndex + 1] == 0 && newMatrix[aIndex][bIndex + 1] == temp && flag == false) { flagMatrix[aIndex][bIndex + 1] = 1; flag = this.getResult(newMatrix, flagMatrix, aIndex, bIndex + 1, newStr.substring(1)); } if (aIndex < (flagMatrix.length - 1) && flagMatrix[aIndex + 1][bIndex] == 0 && newMatrix[aIndex + 1][bIndex] == temp && flag == false) { flagMatrix[aIndex + 1][bIndex] = 1; flag = this.getResult(newMatrix, flagMatrix, aIndex + 1, bIndex, newStr.substring(1)); } return flag; } public static void main(String []args) { char [] matrix = {'A'}; int rows = 1; int cols = 1; char []str = {'A'}; // String ss = String.valueOf(str); Solution solution = new Solution(); System.out.println(solution.hasPath(matrix, rows, cols, str)); } }
看到别人写的,也有很简洁的代码,但是,在我看来,简洁未必就是最好,反而一些易读的代码才更受欢迎,还一个就是解题思路,也比代码的简洁更重要。
别人的code:
/** 用一个状态数组保存之前访问过的字符,然后再分别按上,下,左,右递归 */ public class Solution { public boolean hasPath(char[] matrix, int rows, int cols, char[] str) { int flag[] = new int[matrix.length]; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (helper(matrix, rows, cols, i, j, str, 0, flag)) return true; } } return false; } private boolean helper(char[] matrix, int rows, int cols, int i, int j, char[] str, int k, int[] flag) { int index = i * cols + j; if (i < 0 || i >= rows || j < 0 || j >= cols || matrix[index] != str[k] || flag[index] == 1) return false; if(k == str.length - 1) return true; flag[index] = 1; if (helper(matrix, rows, cols, i - 1, j, str, k + 1, flag) || helper(matrix, rows, cols, i + 1, j, str, k + 1, flag) || helper(matrix, rows, cols, i, j - 1, str, k + 1, flag) || helper(matrix, rows, cols, i, j + 1, str, k + 1, flag)) { return true; } flag[index] = 0; return false; } }
对代码略做解释:
子函数helper(…)的含义是在当前的二维数组的(i, j)这个位置,与str数组的第k项值是否相等,当然前提是该位置之前并没有走过。
本代码中,仍然沿用一维数组,这是值得学习的地方,另外一个,就是终止条件的运用,在该代码中,把下标越界也当做一个终止条件,这是我之前没有想到的。
下面再贴一个我重新按照此思想码的代码。哎,看着别人写的代码,感觉很容易就能实现,但当自己一点点的去码的时候,会发现各种bug。。。
code:
package niuke.sward2offer.pathInMatrix; /** * 重写的代码 * * T: 矩阵中的路径 * * 题目描述 * 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。 * 路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。 * 如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 * 例如 a b c e s f c s a d e e 矩阵中包含一条字符串"bccced"的路径, * 但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。 * * date: 2015.11.5 * @author SSS * */ public class Solution1 { public boolean hasPath(char []matrix, int rows, int cols, char []str) { // 标记位 int []flagMatrix = new int[matrix.length]; for (int i = 0; i < flagMatrix.length; i++) { flagMatrix[i] = 0; } for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { int index = cols * i + j; if (str[0] == matrix[index]) { // 只有在第一个相等的时候才进行比较,否则直接略过,效率更高 if (str.length == 1) { // 要判断该str的长度是否只为1,如果是1,那就不用子函数 return true; } if (this.isHasPath(matrix, flagMatrix, rows, cols, i, j, str, 0)) { return true; } } } } return false; } public boolean isHasPath(char []matrix, int []flagMatrix, int rows, int cols, int a, int b, char []str, int k) { int index = cols * a + b; if (k == str.length) { return true; } if (a < 0 || a == rows || b < 0 || b == cols || flagMatrix[index] == 1 || matrix[index] != str[k]) { return false; } flagMatrix[index] = 1; if (this.isHasPath(matrix, flagMatrix, rows, cols, a, b - 1, str, k + 1) || this.isHasPath(matrix, flagMatrix, rows, cols, a - 1, b, str, k + 1) || this.isHasPath(matrix, flagMatrix, rows, cols, a, b + 1, str, k + 1) || this.isHasPath(matrix, flagMatrix, rows, cols, a + 1, b, str, k + 1) ) { return true; } flagMatrix[index] = 0; return false; } public static void main(String []args) { char [] matrix = {'A','B','C','E','S','F','C','S','A','D','E','E'}; int rows = 3; int cols = 4; char []str = {'A','B','C','C','E','D'}; // String ss = String.valueOf(str); Solution1 solution1 = new Solution1(); System.out.println(solution1.hasPath(matrix, rows, cols, str)); } }
0 0
- 《剑指offer》——矩阵中的路径
- 剑指offer——矩阵中的路径
- 剑指offer——矩阵中的路径
- 剑指offer—矩阵中的路径
- 剑指offer—矩阵中的路径
- 剑指offer — 矩阵中的路径
- 剑指offer(C++)——矩阵中的路径
- 剑指offer——矩阵中的路径(好)
- 剑指Offer—65—矩阵中的路径
- 剑指offer——65.矩阵中的路径
- 剑指offer--矩阵中的路径
- 《剑指offer》矩阵中的路径
- 剑指offer:矩阵中的路径
- [剑指offer]矩阵中的路径
- 剑指offer-矩阵中的路径
- 剑指offer 矩阵中的路径
- 剑指offer-矩阵中的路径
- 剑指offer-矩阵中的路径
- java根据手机号获取归属地
- C++读写文件保存至容器list中
- Win7 Eclipse Hadoop2.4插件配置
- web前端学习-kindeditor
- 机器学习实战笔记之三(决策树)
- 《剑指offer》——矩阵中的路径
- Leetcode || Implement strStr()
- 使用ActionMode实现ListView的多选功能
- method / function
- paip.解决 数据库mysql增加列 字段很慢添加字段很慢
- Android-Uiautomator:如何实现双击效果
- poj acm 2387 Til the Cows Come Home
- Toolbar 标题居中
- 程序员应知道这十大面向对象设计原则