0、前言
本题来自leetcode
1、题目描述
2、解题思路
这是一道回溯法的典型题目,所以需要应用递归的思路来解决。
我们可以形象的用树状结构来表示。在某一步有n个选项:如果当前选项符合要求,我们则进入当前选项中,假设这个选项有k个选项,我们则再根据条件进行判断,当走到叶节点也符合要求的时候,那些被我们选择的由根到叶的路径则是最终结果。如果当前选项不符合要求,我们则回溯到他的父节点,去选择它具有的别的选项,如果都不符合,则回溯到父节点的父节点,连根节点都不再具有符合的选项的话,则本次搜索失败。
一个成功的例子:
a b t g c f c s j d e h word: “bfch”
我们看一下以b为根节点所构成的查询树(查找顺序为:左右下上)
b先寻找周围的选项a,发现不行后返回b,再找t后也不行再返回b,最后找到f发现可以后继续找f的选项。第一个c后发现可以,继续找c的选项j后不行返回c,没有别的选项后返回f,然后找f的第二个选项c,可以继续下探后找到其选项s后不行,返回c继续找发现e可以。到达word最后一个字符后匹配成功。
通过模拟查找后我们确定代码需要用到以下几条:需要时刻知道矩阵(传参建议引用,不生成新的空间,可以使得速度加快),需要知道当前处在矩阵中的位置,需要时刻知道word(也要引用),需要知道当前的匹配word在哪个字符,需要知道什么时候匹配成功。
要注意的点为:不能访问矩阵越界,不能访问已经访问的元素(直接原地哈希法即可)。
3、代码实现
class Solution {
public:
bool exist(vector<vector<char>>& board, string word) {
for (int row = 0; row < board.size(); row++) {
for (int col = 0; col < board[row].size(); col++) {
if (dfs(board, row, col, word, 0)) { // 成功匹配
return true;
}
}
}
return false;
}
// 矩阵,行,列,字符串,匹配位置
bool dfs(vector<vector<char>>& board, int row, int col, string &word, int loc) {
if (loc >= word.size()) return true; // 匹配成功
if (row >= board.size() || row < 0 || col >= board[row].size() || col < 0) return false; // 超矩阵范围
if (board[row][col] != word[loc]) return false; // 匹配失败 or 被标记
board[row][col] += 100; // 标记
// 匹配返回
bool res = dfs(board, row + 1, col, word, loc + 1) ||
dfs(board, row - 1, col, word, loc + 1) ||
dfs(board, row, col + 1, word, loc + 1) ||
dfs(board, row, col - 1, word, loc + 1);
board[row][col] -= 100; // 解除标记
return res; // 返回答案
}
};
4、小节
大佬还有什么别的解法吗?欢迎评论区留言啊!