题目:
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
class Solution {
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)
{
// k = len(word) - 1 ,即字符串 word 已全部匹配。
if (dfs(board, word, i, j, 0)) // 看回溯函数的终止条件,只有当 if(k==word.length()-1) 才算 true
return true; // 所以控制了,当回溯函数为 true,主函数才返回 true
}
}
return false;
}
private:
// 递归参数
bool dfs(vector<vector<char>>& board, string& word, int i, int j, int k)
{
// 只要有一个不符合,就返回假
if (i >= board.size() || i < 0 || j >= board[0].size() || j < 0 || board[i][j] != word[k]) return false;
if (k == word.length() - 1) return true;
char tmp = board[i][j]; // 暂时存起来,最后回溯还要用到
board[i][j] = '/';
/**********************************************************************************************************/
// 第一种写法,写成for循环的形式,这种还是比较优秀的
// (-1, 0) 上 (0, 1) 右 (1, 0) 下 (0, -1) 左
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; // 用来循环以(i, j)为下标的周围的四个象限
for (int t = 0; t < 4; ++t)
{
int m = i + dx[t];
int n = j + dy[t];
if (dfs(board, word, m, n, k + 1)) return true; // 四种情况,有一个成功就直接返回真了
}
board[i][j] = tmp; // 回溯
return false;
// // 第二种写法,看起来就有点蠢了,gg ,这四个递归的方向是 下,上,右,左
// bool res = dfs(board, word, i + 1, j, k + 1) ||
// dfs(board, word, i - 1, j, k + 1) ||
// dfs(board, word, i, j + 1, k + 1) ||
// dfs(board, word, i, j - 1, k + 1);
// board[i][j] = word[k];
// return res;
/**********************************************************************************************************/
}
};