请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。
[["a","b","c","e"],
["s","f","c","s"],
["a","d","e","e"]]
但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
解题思路:深度优先遍历,重点是了解递归前进段和回退段的作用。
前进段,改变路径标志,回退段恢复路径标志。 递归就像洋葱,进前可以影响输入,退出可以影响输出;
/**
* @param {character[][]} board
* @param {string} word
* @return {boolean}
*/
var exist = function(board, word) {
if(board.length === 0) return false;
const rowLen = board.length;
const colLen = board[0].length;
let found =false;
const boardFlag = [];
for(let i =0;i<rowLen;i++){
boardFlag[i]=[];
for(let j=0; j<colLen;j++){
boardFlag[i][j]=1
}
}
const backTrack = (pre, row, col) => {
if(found || !word.startsWith(pre)) {
return;
}
if(pre === word){
found = true;
return ;
}
if( row+1< rowLen && boardFlag[row+1][col]){
boardFlag[row+1][col] =0; // 设置标签
backTrack(pre+board[row+1][col],row+1,col)
boardFlag[row+1][col] =1; // 恢复标签
}
if(row-1>=0 && boardFlag[row-1][col] ){
boardFlag[row-1][col]=0
backTrack(pre+board[row-1][col], row-1,col);
boardFlag[row-1][col]=1
}
if(col+1 <colLen && boardFlag[row][col+1]){
boardFlag[row][col+1] = 0;
backTrack(pre+board[row][col+1],row,col+1)
boardFlag[row][col+1] = 1
}
if(col-1 >=0 && boardFlag[row][col-1]){
boardFlag[row][col-1] = 0
backTrack(pre+board[row][col-1],row,col-1)
boardFlag[row][col-1] = 1
}
}
for(let row=0; row< rowLen; row++){
for(let col=0; col<colLen; col++){
if(board[row][col]===word[0]){
boardFlag[row][col] = 0
backTrack(board[row][col],row, col);
boardFlag[row][col] = 1
}
}
}
return found;
};