每日一题:二维字符数组中的单词搜索
引言
:给定一个二维字符数组 board 和一个单词 word,判断 word 是否在 board 中出现。单词由相邻单元格(上下左右)的字母连接而成,同一单元格的字母不能重复使用。使用深度优先搜索(DFS)和回溯法,从每个起点尝试匹配 word,通过递归搜索四个方向,并用临时标记避免重复访问。匹配成功返回 true,否则回溯并继续搜索。
题目描述
给定一个二维字符数组 board
和一个字符串 word
,判断 word
是否在 board
中出现。单词可以由数组中相邻单元格的字母连接而成,其中“相邻”单元格指的是上下左右相邻的单元格。同一个单元格的字母不能多次使用。
示例
输入
vector<vector<char>> board = {
{
'X', 'Y', 'Z', 'E'},
{
'S', 'F', 'Z', 'S'},
{
'X', 'D', 'E', 'E'}
};
string word1 = "XYZZED";
string word2 = "SEE";
string word3 = "XYZY";
输出
true // "XYZZED" 可以在 board 中找到
true // "SEE" 可以在 board 中找到
false // "XYZY" 无法在 board 中找到
题目分析
1. 问题分解
- 我们需要在二维字符数组
board
中搜索是否存在一条路径,使得路径上的字符按顺序连接起来恰好等于word
。 - 路径的相邻单元格只能是上下左右四个方向。
- 同一个单元格的字符不能重复使用。
2. 解决思路
- 遍历
board
中的每一个字符,作为搜索的起点。 - 对于每个起点,使用深度优先搜索(DFS)和回溯的方法,尝试匹配
word
的每一个字符。 - 如果某个路径匹配成功,返回
true
;否则,继续尝试其他路径。
3. 关键点
- 递归回溯:通过递归实现深度优先搜索,并通过回溯恢复
board
的状态。 - 边界条件:需要检查搜索时是否越界,以及当前字符是否匹配。
- 状态标记:为了避免重复使用同一个单元格的字符,需要在搜索过程中临时修改
board
的值,并在回溯时恢复。
代码实现
以下是完整的代码实现:
#include <vector>
#include <string>
using namespace std;
class Solution {
public:
bool exist(vector<vector<char>>& board, string word) {
int m = board.size(); // 获取 board 的行数
int n = board[0].size(); // 获取 board 的列数
// 遍历 board 中的每一个字符,作为搜索的起点
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (search(board, word, i, j, 0)) {
return true; // 如果找到匹配路径,返回 true
}
}
}
return false; // 如果遍历完所有起点都没有找到匹配路径,返回 false
}
bool search(vector<vector<char