给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻"单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

这道题,有三个特点
-
起点不确定,word 的第一个字母,可能在任意一个格子
-
每一步都有四种选择
-
当前的路不行,需要换一条路试一试
我们可以定义一个DFS函数,dfs(i, j, index),从坐标(i,j)开始,尝试匹配word[index],index表示:当前要匹配第几个字符
word = "A B C C E D"
index 0 1 2 3 4 5
成功的条件就是index === word.length
失败的条件是
javascript
if (i < 0 || i >= m || j < 0 || j >= n || visited[i][j] || board[i][j] !== word[index]) {
return false
}
因为题目告诉我们每个字母只能使用一次,所以我们要添加判断,
visited[i][j] = true,含义就是这个格子,在当前路径中已经用过了
回溯的灵魂是撤销选择,所以我们在递归探索之后需要撤销选择,也就是visited[i][j] = false
完整的代码是
javascript
/**
* @param {character[][]} board
* @param {string} word
* @return {boolean}
*/
var exist = function(board, word) {
const m = board.length
const n = board[0].length
// 记录是否访问过
const visited = Array.from({ length: m }, () =>
Array(n).fill(false)
)
const dfs = (i, j, index) => {
// 单词匹配完成
if (index === word.length) return true
// 越界 or 不匹配 or 已访问
if (
i < 0 || i >= m ||
j < 0 || j >= n ||
visited[i][j] ||
board[i][j] !== word[index]
) {
return false
}
// 做选择
visited[i][j] = true
// 向四个方向搜索
const found =
dfs(i + 1, j, index + 1) ||
dfs(i - 1, j, index + 1) ||
dfs(i, j + 1, index + 1) ||
dfs(i, j - 1, index + 1)
// 回溯(撤销选择)
visited[i][j] = false
return found
}
// 从每个格子作为起点尝试
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (dfs(i, j, 0)) return true
}
}
return false
};