单词搜索(Word Search)
给定一个 m x n 的二维字符网格 board 和一个字符串 word,判断 word 是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格(水平或垂直相邻)构成,同一个单元格内的字母不允许被重复使用。
示例
1 | 输入: |
方法:回溯法(DFS + 剪枝)
核心思想
- 遍历网格:对每个单元格作为起点,尝试匹配
word的第一个字符。 - DFS 回溯:
- 从当前单元格出发,向 上、下、左、右 四个方向递归搜索。
- 如果当前字符匹配,继续搜索下一个字符;否则回溯。
- 避免重复使用:用
visited矩阵或临时修改board标记已访问的单元格。
JavaScript 代码
1 | var exist = function(board, word) { |
时间复杂度
- 最坏情况:O(m × n × 4^L),其中
L是word的长度(每个单元格有 4 个方向的选择)。 - 剪枝优化:实际运行时,不匹配的路径会提前终止。
关键点
- 递归终止条件:
index === word.length:成功匹配整个单词。- 越界或字符不匹配:直接返回
false。
- 避免重复访问:
- 临时修改
board[i][j]为特殊字符(如#),递归结束后恢复。
- 临时修改
- 方向搜索:
- 每次递归尝试 上、下、左、右 四个方向。
示例解析
以输入 board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]] 和 word = "ABCCED" 为例:
- 从
(0,0)开始(A匹配word[0]):- 向下到
(1,0)(S≠B)→ 回溯。 - 向右到
(0,1)(B匹配word[1]):- 继续向右到
(0,2)(C匹配word[2]):- 向下到
(1,2)(C匹配word[3]):- 向下到
(2,2)(E匹配word[4]):- 向左到
(2,1)(D匹配word[5])→ 返回true。
- 向左到
- 向下到
- 向下到
- 继续向右到
- 向下到
变种问题
单词搜索 II(多个单词)
给定一个 board 和一个单词列表 words,返回所有能在 board 中匹配的单词。
优化方法:使用 Trie 树(字典树) 预处理 words,结合回溯法。
允许重复使用单元格
若允许重复使用单元格,需调整 visited 逻辑(一般不常见)。
总结
| 方法 | 时间复杂度 | 空间复杂度 | 适用场景 |
|---|---|---|---|
| 回溯法(DFS) | O(m × n × 4^L) | O(L)(递归栈) | 通用 |
| Trie + 回溯 | O(m × n × 4^L) | O(T)(Trie 节点数) | 多单词搜索 |
推荐:
- 单单词搜索直接用回溯法。
- 多单词搜索用 Trie 优化。