题目描述
Given a 2D board and a word, find if the word exists in the grid.
The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.
For example, Given board =
word =
"ABCCED"
, -> returnstrue
,word =
"SEE"
, -> returnstrue
,word =
"ABCB"
, -> returnsfalse
.
解法
这道题目……好吧,也是非常经典的回溯类型的题目,它的思路是这样的:
枚举board中的一条路径,并且在枚举的过程中一边检查是否能够匹配上word,如果顺利的匹配完了所有word的字符,就说明找到了;如果枚举结束之后仍然没有找到,就说明不存在。
所以,对于这样的方法,我们可以使用回溯法来进行枚举,在枚举中,我们需要保存如下几个值:当前已经匹配的长度l
,现在路径的尾部(i, j)
以及哪些格子已经在路径当中使用了used[n][m]
,即:
bool backtracking(vector<vector<char>>& board, string &word, vector<vector<bool>> &used, int i, int j, int l)
在这个过程中,我们需要对枚举的路径,进行合法判断,不能使用已经使用过的格子,也不能穿到board的外面:
// 判断该位置是否合法
if (i < 0 || j < 0 || i == board.size() || j == board[0].size() || used[i][j]) return false;
// 判断该位置是否匹配
if (word[l] != board[i][j]) return false;
在确认了当前位置合法之后,就可以直接从相邻的4个格子里选一个,作为路径的下一个格子了!
这道题目相对简单,主要需要考虑的就是判断合法和判断完成的顺序问题~
参考代码
class Solution {
public:
bool exist(vector<vector<char>>& board, string word) {
// 获取n, m并判断边界情况
int n = board.size();
if (n == 0) return false;
int m = board[0].size();
if (m == 0) return false;
// 枚举单词的起点,用回溯的方式进行查找
vector<vector<bool>> used(n, vector<bool>(m, false));
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (backtracking(board, word, used, i, j, 0)) return true;
return false;
}
// 方向向量,用以表述4个方向
const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};
// 回溯方法
bool backtracking(vector<vector<char>>& board, string &word, vector<vector<bool>> &used, int i, int j, int l) {
// 如果已经匹配了所有的字符,说明已经找到了
if (l == word.length()) return true;
// 判断该位置是否合法
if (i < 0 || j < 0 || i == board.size() || j == board[0].size() || used[i][j]) return false;
// 判断该位置是否匹配
if (word[l] != board[i][j]) return false;
// 设该位置为已经使用
used[i][j] = true;
// 否则就枚举接下来字符的位置
for (int k = 0; k < 4; k++) {
// 递归进入下一层
if (backtracking(board, word, used, i + dx[k], j + dy[k], l + 1)) return true;
}
// 找不到就只能返回false
used[i][j] = false;
return false;
}
};
怎一个优雅了得
y原文:https://www.tianmaying.com/tutorial/LC79