LeetCode 面试经典 150_回溯_单词搜索(104_79_C++_中等)
题目描述:
给定一个 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
提示:
m == board.length
n = board[i].length
1 <= m, n <= 6
1 <= word.length <= 15
board 和 word 仅由大小写英文字母组成
题解:
解题思路:
思路一(深度优先搜索(回溯)):
1、根据搜索的过程,可以容易的推出使用深度优先 的方法进行搜素。
具体思路如下:
① 对图中的每个结点进行一次深度优先搜索 ,若存在匹配则返回true,不存在匹配则返回 false。
② 在进行深度优先遍历的时候先判断表格中字母与word中第一个字母是否相同,若相同则进行深度优先搜索,每次搜索依次与word中的下一个字母进行比较。
③ 若每次比较字母相同则将此字母标记为已搜索 ,继续进行搜索,搜索到所有 word 中的字母则返回 true 。
另一种代码实现形式可参考此文章:LeetCode 热题 100_单词搜索(60_79_中等_C++)(深度优先搜索(回溯))(初始化二维vector的大小)
2、复杂度分析:
① 时间复杂度:一个非常宽松的上界为 O(MN3L ),M,N 为网格的长度与宽度。L 为字符串 word 的长度。在图上每个点进行一个深度搜先搜索,总共有 MN 个点。搜索失败,最深的搜索的深度为(L-1),每个点有上下左右四个搜索方向,方式搜索过的点不进行搜索,所以为 3L。所以总的时间复杂度为 O(MN 3L )。
② 空间复杂度:
代码实现
代码实现(思路一(深度优先搜索(回溯))):
cpp
class Solution {
bool backtracking(vector<vector<char>>& board, string& word, int row, int col, int i) {
if (i == word.size()) {
return true; // 找到完整单词
}
// 边界条件和字符匹配
if (row < 0 || row >= board.size() || col < 0 || col >= board[0].size() || board[row][col] != word[i]) {
return false; // 超出边界或字符不匹配
}
// 标记当前单元格为已访问
char temp = board[row][col];
board[row][col] = '#'; // 使用特殊字符标记为已访问
// 进行四个方向的递归搜索
bool found = backtracking(board, word, row - 1, col, i + 1) || // 上
backtracking(board, word, row + 1, col, i + 1) || // 下
backtracking(board, word, row, col - 1, i + 1) || // 左
backtracking(board, word, row, col + 1, i + 1); // 右
// 回溯
board[row][col] = temp; // 恢复状态
return found; // 返回结果
}
public:
bool exist(vector<vector<char>>& board, string word) {
for (int i = 0; i < board.size(); ++i) {
for (int j = 0; j < board[0].size(); ++j) {
if (backtracking(board, word, i, j, 0)) {
return true; // 找到单词
}
}
}
return false; // 未找到单词
}
};
以思路一为例进行调试
cpp
#include<iostream>
#include <vector>
using namespace std;
class Solution {
bool backtracking(vector<vector<char>>& board, string& word, int row, int col, int i) {
if (i == word.size()) {
return true; // 找到完整单词
}
// 边界条件和字符匹配
if (row < 0 || row >= board.size() || col < 0 || col >= board[0].size() || board[row][col] != word[i]) {
return false; // 超出边界或字符不匹配
}
// 标记当前单元格为已访问
char temp = board[row][col];
board[row][col] = '#'; // 使用特殊字符标记为已访问
// 进行四个方向的递归搜索
bool found = backtracking(board, word, row - 1, col, i + 1) || // 上
backtracking(board, word, row + 1, col, i + 1) || // 下
backtracking(board, word, row, col - 1, i + 1) || // 左
backtracking(board, word, row, col + 1, i + 1); // 右
// 回溯
board[row][col] = temp; // 恢复状态
return found; // 返回结果
}
public:
bool exist(vector<vector<char>>& board, string word) {
for (int i = 0; i < board.size(); ++i) {
for (int j = 0; j < board[0].size(); ++j) {
if (backtracking(board, word, i, j, 0)) {
return true; // 找到单词
}
}
}
return false; // 未找到单词
}
};
int main(int argc, char const *argv[])
{
// 初始化网格
vector<vector<char>> board = {{'A','B','C','E'},{'S','F','C','S'},{'A','D','E','E'}};
// 初始化要查找的单词 'word'
string word = "ABCCED";
// 创建 Solution 类的对象 's',用于调用 'exist' 函数
// 如果找到了,输出 "true"
Solution s;
if (s.exist(board,word))
{
cout<<"true";
}else{
cout<<"false";
}
return 0;
}
LeetCode 面试经典 150_回溯_单词搜索(104_79)原题链接
欢迎大家和我沟通交流(✿◠‿◠)