题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如
矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
思路分析
基础思想是岛问题中的传染解法。(很形象,一传四,中的人继续传)
- 用一个数组作为标志数组,记录路径是否走过此处,1为走过
- 从[0][0]位置开始遍历
- 题目中给的是一维数组,先做转化,确定二维转成一维数组此时的位置
- 递归终止即返回false的条件:下标越界;此位置已经走过;当前位置的值和字符串要求不符
- 递归成功即返回true的条件:字符串的索引到达最后一位
- 不断搜索周围四个格子是否符合要求,只要有一个符合就继续找这个的周围四个格子
- 此时,四个格子都不符合要求,将此处的标志置0,换个路线走
代码实现
public static boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
if (matrix == null) {
return false;
}
int[][] dpMatrix = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (process(matrix, rows, cols, i, j, str, 0, dpMatrix)) {
return true;
}
}
}
return false;
}
public static boolean process(char[] matrix, int rows, int cols, int row, int col, char[] str, int index, int[][] dp) {
int cur = cols * row + col;
if (row >= rows || col >= cols || row < 0 || col < 0 || dp[row][col] == 1 || matrix[cur] != str[index]) {
return false;
}
if (index == str.length - 1) {
return true;
}
//没走过
//开始将走过的位置置1
dp[row][col] = 1;
if (process(matrix, rows, cols, row + 1, col, str, index + 1, dp) ||
process(matrix, rows, cols, row - 1, col, str, index + 1, dp) ||
process(matrix, rows, cols, row, col + 1, str, index + 1, dp) ||
process(matrix, rows, cols, row, col - 1, str, index + 1, dp)) {
return true;
}
//走不通,还原
dp[row][col] = 0;
return false;
}