题目描述


// 12. 矩阵中的路径
// 力扣
// 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某
// 字符串所有字符的路径。路径可以从矩阵中的任意一格开始,
// 每一步可以在矩阵中向左、右、上、下移动一格。如果一条路
// 径经过了矩阵的某一格,那么该路径不能再次进入该格子。例
// 如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径
// 中的字母用加粗标出)。
// [["a","b","c","e"],
// ["s","f","c","s"],
// ["a","d","e","e"]]
// 但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占
// 据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
// 牛客
// 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所
// 有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在
// 矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩
// 阵中的某一个格子,则该路径不能再进入该格子。 例如
// [["a","b","c","e"],
// ["s","f","c","s"],
// ["a","d","e","e"]]
// 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因
// 为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能
// 再次进入该格子。
题解
/////////////////////////////////////// 回溯搜索法 ///////////////////////////////////////
构建待搜索矩阵同尺寸的布尔矩阵marked,用于标记该位置元素是否被使用过。
设置路径步长pathLen,用于同步搜索目标的长度。
遍历待搜索矩阵matrix每一个位置的元素,对该位置的元素做所有方向的搜索,搜索不到就回溯到原状态,之前修改的marked和pathLen要重置。
// 牛客
// 运行时间 12ms
// 占用内存 9592KB
public class Solution {
private final static int[][] next = {{0,-1}, {0,1}, {-1,0}, {1,0}}
private int rows
private int cols
// 解题函数
public boolean hasPath(char[] array, int rows, int cols, char[] str) {
if (rows == 0 || cols == 0)
return false
this.rows = rows
this.cols = cols
boolean[][] marked = new boolean[rows][cols]
char[][] matrix = buildMatrix(array)
// 两层for循环,遍历待搜索矩阵matrix的所有元素,第r行第c列元素为matrix[c][r]
for (int r = 0
for (int c = 0
if (backTracking(matrix, str, marked, r, c, 0)) {
return true
}
}
}
return false
}
// 回溯搜索法
// 输入变量:待搜索矩阵matrix,搜索目标str,状态标记矩阵marked(初始化为全false), 遍历行r,遍历列c,已遍历的路径步长pathLen(初始化为0)
// 每一次backTracking搜索,路径长度pathLen将+1,搜索失败,则回溯进行下一次for遍历
// pathLen又会重置为0,marked也会重置为全false。
private boolean backTracking(char[][] matrix, char[] str, boolean[][] marked, int r, int c, int pathLen) {
if (pathLen == str.length) // 如果遍历路径步长等于搜索目标str的长度,返回true
return true
if (r < 0 || r >= rows || c < 0 || c >= cols) // 如果遍历行和列超出边界,返回false,(回到上一次marked的标记和路径步数pathLen,即进行了回溯)
return false
if (marked[r][c]) // 如果遍历元素被使用过,返回false,进行回溯
return false
if (matrix[r][c] != str[pathLen]) // 如果搜索矩阵遍历元素与当前路径步数对应的搜索目标字符不相等,返回false,进行回溯
return false
marked[r][c] = true
// 开始以当前遍历元素matrix[r][c]为起点进行搜索,for循环取next中左右上下四个方向,递归backTracking进行搜索
// 路径pathLen+1
for (int[] dic : next) {
if (backTracking(matrix, str, marked, r + dic[0], c + dic[1], pathLen + 1)) {
return true
}
}
// 当前遍历元素搜索结束,未发现目标,元素标记重置回false
marked[r][c] = false
return false
}
// 将数组char[]转为矩阵char[][]
public char[][] buildMatrix(char[] array) {
char[][] matrix = new char[rows][cols]
int idx = 0
for (int r = 0
for (int c = 0
matrix[r][c] = array[idx++]
}
}
return matrix
}
}
// 力扣
// 和牛客原理是一样的
// 执行用时:7 ms, 在所有 Java 提交中击败了40.96%的用户
// 内存消耗:40.1 MB, 在所有 Java 提交中击败了87.40%的用户
class Solution {
private int rows
private int cols
private final int[][] next = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}}
public boolean exist(char[][] board, String word) {
this.rows = board.length
this.cols = board[0].length
char[] wordarray = word.toCharArray()
if (rows == 0 || cols == 0)
return false
boolean[][] marked = new boolean[rows][cols]
for (int r = 0
for (int c = 0
if (backTracking(board, wordarray, marked, r, c, 0)) {
return true
}
}
}
return false
}
public boolean backTracking(char[][] matrix, char[] str, boolean[][] marked, int r, int c, int pathLen) {
if (pathLen == str.length)
return true
if (r < 0 || r >= rows || c < 0 || c >= cols)
return false
if (marked[r][c])
return false
if (matrix[r][c] != str[pathLen])
return false
marked[r][c] = true
for (int[] dic : next) {
if (backTracking(matrix, str, marked, r + dic[0], c + dic[1], pathLen + 1))
return true
}
marked[r][c] = false
return false
}
}