题目如下:
解题思路:
- 本题首先想到的思路就是遍历每一个元素进行 深度优先搜索DFS ,当找到符合条件的字符顺序即返回。在一次DFS搜索过程中,对已经遍历过的元素我们需要将其标记为已搜索状态;
- 但在DFS前后需要注意的是,必须要保证执行前后程序面对问题的状态是相同的,因此当前问题缩小为子问题时所做的对当前问题状态产生影响的事情应该全部失效,那么就需要在 回溯 时还原现场从而避免出现下图的情况。
- 在经过 DFS + 回溯 后我们能得到正确结果,但是对如下图特殊用例却会出现超时的现象,因此我们还需要用到 剪枝 的思路,在找到结果后立即结束所有后续DFS搜索,返回结果。
代码如下:
class Solution {
public:
bool exist(vector<vector<char>>& board, string word) {
if(board.size() == 0 || board[0].size() == 0)
return false;
for(int i = 0; i < board.size(); i++){
for(int j = 0; j < board[0].size(); j++){
if(dfs_backtrack(board, word, i, j, 0)) //遍历每一个元素进行DFS搜索
return true;
}
}
return false;
}
bool dfs_backtrack(vector<vector<char>>& board, string word, int i, int j, int cur) {
if(cur == word.size()) //找到,结束搜索
return true;
else if(i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || board[i][j] != word[cur]) //不满足条件,结束搜索
return false;
else{
int temp = board[i][j];
board[i][j] = '.'; //DFS过程中,对已经遍历过得元素标记为搜索过
bool res1 = dfs_backtrack(board, word, i+1, j, cur+1);
if(res1) return true; //找到后就及时剪枝,停止DFS搜索,不然会超时
bool res2 = dfs_backtrack(board, word, i-1, j, cur+1);
if(res2) return true;
bool res3 = dfs_backtrack(board, word, i, j+1, cur+1);
if(res3) return true;
bool res4 = dfs_backtrack(board, word, i, j-1, cur+1);
if(res4) return true;
board[i][j] = temp; //没有增加额外的标记判断数组,为了不影响下次DFS搜索,需要回溯回复数组元素
//return (res1 || res2 || res3 || res4);
return false;
}
}
};