例如:
board = [ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ] Given word = "ABCCED", return true. Given word = "SEE", return true. Given word = "ABCB", return false.
难度:【medium】
思路:利用深度优先搜索(dfs),在递归的时候要记录哪些是已经走过的位置,不能重复走,可以使用vector<pair<int, int>>存放已经走过的位置,也可以直接修改矩阵(如果允许的情况下),将该元素改为矩阵中不可能出现的某个字符,如‘\0’,'*' 等等,在回溯的时候在还原回来。
方法1:用vector<pair<int, int>>记录已经访问过的位置。
bool isVisited(int i, int j, vector<pair<int, int>>& visited) {
for (int k = 0; k < visited.size(); ++k) {
if (visited[k].first == i && visited[k].second == j) {
return true;
}
}
return false;
}
bool find(vector<vector<char>>& board, int i, int j, string word, int k, vector<pair<int, int>>& visited) {
if (i > board.size() - 1 || j > board[0].size() - 1 ||
i < 0 || j < 0) { return false; }
if (isVisited(i, j, visited)) { return false; }
if (board[i][j] != word[k]) { return false; }
if (k == word.size() - 1) {
return true;
}
visited.push_back(make_pair(i, j));
++k;
if (find(board, i + 1, j, word, k, visited) ||
find(board, i - 1, j, word, k, visited) ||
find(board, i, j + 1, word, k, visited) ||
find(board, i, j - 1, word, k, visited)) {
return true;
} else {
--k;
visited.pop_back();
return false;
}
}
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 (board[i][j] == word[0]) {
vector<pair<int, int>> visited;
if (find(board, i, j, word, 0, visited)) {
return true;
}
}
}
}
return false;
}
方法2:基于方法1的优化版,直接修改矩阵中的元素用来标记已经走过的节点。
// 优化版, 不使用额外的容器记录是否已经访问过,而是通过修改board进行标记
bool find(vector<vector<char>>& board, int i, int j, string word, int k) {
if (i > board.size() - 1 || j > board[0].size() - 1 ||
i < 0 || j < 0) { return false; }
if (board[i][j] != word[k]) { return false; }
if (k == word.size() - 1) { return true; }
board[i][j] = '\0';
++k;
if (find(board, i + 1, j, word, k) ||
find(board, i - 1, j, word, k) ||
find(board, i, j + 1, word, k) ||
find(board, i, j - 1, word, k)) {
return true;
} else {
--k;
board[i][j] = word[k];
return false;
}
}
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 (board[i][j] == word[0]) {
vector<pair<int, int>> visited;
if (find(board, i, j, word, 0)) {
return true;
}
}
}
}
return false;
}