Files
interview/16-LeetCode Hot 100/单词搜索.md
yasinshaw e75e4778b1 feat: add 19 LeetCode Hot 100 medium problems with detailed solutions
批量生成 19 道 LeetCode Hot 100 Medium 难度题目,每道题包含:
- 题目描述和示例
- 多种解题思路(回溯、DP、双指针等)
- Go 和 Java 双语解答
- 完整的测试用例
- 复杂度分析
- 进阶问题
- P7 加分项(深度理解、实战扩展、变形题目)

新增题目:
1. 盛最多水的容器 (Container With Most Water) - LeetCode 11
2. 电话号码的字母组合 (Letter Combinations) - LeetCode 17
3. 删除链表的倒数第N个结点 - LeetCode 19
4. 括号生成 - LeetCode 22
5. 最长回文子串 - LeetCode 5
6. 子集 - LeetCode 78
7. 单词搜索 - LeetCode 79
8. 柱状图中最大的矩形 - LeetCode 84
9. 最大正方形 - LeetCode 221
10. 完全平方数 - LeetCode 279
11. 最长连续序列 - LeetCode 128
12. 除自身以外数组的乘积 - LeetCode 238
13. 最小栈 - LeetCode 155
14. 二叉树的中序遍历 - LeetCode 94
15. 二叉树的最大深度 - LeetCode 104
16. 翻转二叉树 - LeetCode 226
17. 对称二叉树 - LeetCode 101
18. 路径总和 - LeetCode 112
19. 从前序与中序遍历序列构造二叉树 - LeetCode 105

所有代码均包含:
- 清晰的注释说明
- 完整的可运行测试用例
- 时间和空间复杂度分析
- 优化技巧和变形题目

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-05 12:26:07 +08:00

176 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 单词搜索 (Word Search)
## 题目描述
给定一个 `m x n` 二维字符网格 `board` 和一个字符串单词 `word`。如果 `word` 存在于网格中,返回 `true`;否则,返回 `false`
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻"单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
### 示例
**示例 1**
```
输入board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出true
```
**示例 2**
```
输入board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
输出true
```
**示例 3**
```
输入board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
输出false
```
## 解题思路
### 方法一DFS + 回溯(推荐)
**核心思想:**对每个位置进行 DFS搜索是否存在匹配的单词路径。
**算法步骤:**
1. 遍历网格的每个位置
2. 如果当前位置字符匹配单词首字符,开始 DFS
3. DFS 过程中:
- 标记当前已访问
- 向四个方向递归搜索
- 如果找到完整单词,返回 true
- 回溯时撤销访问标记
## 代码实现
### Go 实现
```go
package main
func exist(board [][]byte, word string) bool {
m, n := len(board), len(board[0])
visited := make([][]bool, m)
for i := range visited {
visited[i] = make([]bool, n)
}
var dfs func(i, j, k int) bool
dfs = func(i, j, k int) bool {
// 找到完整单词
if k == len(word) {
return true
}
// 边界检查或不匹配
if i < 0 || i >= m || j < 0 || j >= n ||
visited[i][j] || board[i][j] != word[k] {
return false
}
// 标记访问
visited[i][j] = true
// 向四个方向搜索
found := dfs(i+1, j, k+1) ||
dfs(i-1, j, k+1) ||
dfs(i, j+1, k+1) ||
dfs(i, j-1, k+1)
// 回溯:取消标记
visited[i][j] = false
return found
}
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if board[i][j] == word[0] && dfs(i, j, 0) {
return true
}
}
}
return false
}
```
### Java 实现
```java
public class Solution {
private boolean[][] visited;
private int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
public boolean exist(char[][] board, String word) {
int m = board.length, n = board[0].length;
visited = new boolean[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == word.charAt(0) && dfs(board, word, i, j, 0)) {
return true;
}
}
}
return false;
}
private boolean dfs(char[][] board, String word, int i, int j, int k) {
if (k == word.length()) {
return true;
}
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length ||
visited[i][j] || board[i][j] != word.charAt(k)) {
return false;
}
visited[i][j] = true;
for (int[] dir : directions) {
if (dfs(board, word, i + dir[0], j + dir[1], k + 1)) {
visited[i][j] = false;
return true;
}
}
visited[i][j] = false;
return false;
}
}
```
## 复杂度分析
- **时间复杂度:** O(m × n × 4^L)
- m × n 是网格大小
- L 是单词长度
- 最坏情况每个位置都要搜索 4 个方向
- **空间复杂度:** O(L)
- 递归栈深度最大为 L
- visited 数组 O(m × n)
## P7 加分项
### 变形题目:单词搜索 II
**LeetCode 212:** 给定一个 m x n 二维字符网格 board 和一个单词列表 words返回所有在二维网格和字典中出现的单词。
```go
func findWords(board [][]byte, words []string) []string {
// 构建 Trie 树
trie := buildTrie(words)
result := []string{}
for i := 0; i < len(board); i++ {
for j := 0; j < len(board[0]); j++ {
dfsBoard(board, i, j, trie, &result)
}
}
return result
}
```