79. Word Search(单词搜索)
题目大意
Given an m x n
grid of characters board
and a string word
, return true if word
exists in the grid.
The word can be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once.
中文释义
给定一个 m x n
的字符网格 board
和一个字符串 word
,如果 word
在网格中存在,则返回 true。
单词可以由顺序相邻的单元格中的字母构成,其中相邻单元格水平或垂直相邻。同一个字母单元格不能使用多次。
示例
-
示例 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
- 输入:
限制条件
m == board.length
n = board[i].length
1 <= m, n <= 6
1 <= word.length <= 15
board
和word
仅由小写和大写英文字母组成。
解题思路
使用深度优先搜索(DFS)在网格中寻找单词。从每个单元格开始搜索,检查单词的每个字符是否与网格中的字符匹配,并且保证不重复使用相同的单元格。
步骤说明
- 检查当前索引是否达到单词长度,如果是则找到了单词。
- 检查当前单元格是否越界或者字符不匹配。
- 标记当前单元格为已访问。
- 递归地在四个方向搜索下一个字符。
- 恢复当前单元格的原始值。
- 如果在任意方向找到了单词,则返回 true。
代码
class Solution {
public:
bool dfsSearch(vector<vector<char>>& board, int row, int col, int index, int rows, int cols, const string& word) {
if (index == word.size()) {
return true;
}
if (row < 0 || col < 0 || row >= rows || col >= cols || board[row][col] != word[index]) {
return false;
}
char temp = board[row][col];
board[row][col] = '#'; // 标记为已访问
bool found = dfsSearch(board, row + 1, col, index + 1, rows, cols, word) ||
dfsSearch(board, row, col + 1, index + 1, rows, cols, word) ||
dfsSearch(board, row - 1, col, index + 1, rows, cols, word) ||
dfsSearch(board, row, col - 1, index + 1, rows, cols, word);
board[row][col] = temp; // 恢复原始值
return found;
}
bool exist(vector<vector<char>>& board, string word) {
int rows = board.size(), cols = board[0].size();
reverseWordIfNeeded(word);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (dfsSearch(board, i, j, 0, rows, cols, word)) {
return true;
}
}
}
return false;
}
private:
void reverseWordIfNeeded(string& word) {
if (count(word.begin(), word.end(), word[0]) > count(word.begin(), word.end(), word.back())) {
reverse(word.begin(), word.end());
}
}
};