给定一个
m x n二维字符网格board和一个字符串单词word。如果word存在于网格中,返回true;否则,返回false。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
解法 回溯
思路
进入回溯的条件是要找到字母的开头,接下来朝4个方向去搜寻下一个字母,而下一个字母肯定是要用一个变量 index 来控制的,其他的参数就剩下遍历当前格子的行和列了。
终止条件就是行和列超出范围,当前格子与 word[index] 上的字符对不上,以及之前访问过这个(因为不能重复访问),就返回 false。如果当前 index 递归到 word 最后一个字符,那说明完整了搜索,返回 true 即可。
下面给出的是带 visited 数组的写法,也在注释里给出了不需要额外空间的写法。
代码
function exist(board: string[][], word: string): boolean {
const visited = new Array(board.length).fill(0).map(() => new Array(board[0].length).fill(false));
const dfs = (row, col, index) => {
// board[row][col] === "#"
if (row < 0 || col < 0 || row >= board.length || col >= board[0].length || board[row][col] !== word.charAt(index) || visited[row][col]) return false;
if (index === word.length - 1) return true;
// const temp = board[row][col];
// board[row][col] = "#"
visited[row][col] = true;
const res = dfs(row + 1, col, index + 1) ||
dfs(row, col + 1, index + 1) ||
dfs(row - 1, col, index + 1) ||
dfs(row, col - 1, index + 1);
visited[row][col] = false;
// board[row][col] = temp;
return res;
};
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[0].length; j++) {
if (dfs(i, j, 0)) return true;
}
}
return false;
};
时空复杂度
时间复杂度:O(m * n * L) ,L 是单词长度
空间复杂度:O(m * n + L),如果不用 visted 数组就是递归栈调用的深度 O(L)