类似于迷宫,判断是否存在满足条件的一条路径,还是用深搜的方法来解决。前面做过了许多的深搜题,给出的都是一维数组,字符串等,这里给出的是二维数组,实际上需要变化只是状态的扩展而已,还是用画图的方法来分析。以word = "ABCCED"为例
由于没有规定起点的位置,应该是每一个位置都要尝试。
[0][0]的位置为A,word[0]也为A,符合,扩展状态,相邻的有B和S,B是符合的。继续向下,B的右和下为C,F,C符合条件。
C的左右下为B,E,C,这里的B已经访问过了,而E与word[3]不相等,只有C符合,继续从C向下找.......
推到这里也就有了思路:
设置visited[m][n]数组,用于避免重复
剪枝条件:下标越界则false,字符不匹配则false,重复访问则false
写出代码如下;
class Solution {
public:
/*
* @param board: A list of lists of character
* @param word: A string
* @return: A boolean
*/
bool exist(vector<vector<char>> &board, string &word) {
// write your code here
//m行n列
const int m=board.size();
const int n=board[0].size();
//访问数组,用于保证每个单元中的每个字母最多访问一次
vector<vector<bool>> visited(m,vector<bool>(n,false));
for(int i=0;i<m;i++){
for(int j=0;j<n;++j){
if(DFS(board,word,i,j,0,visited))//找到其中一个可行,返回即可
return true;
}
}
return false;
}
bool DFS(vector<vector<char>> &board, string &word,int x,int y,int index,vector<vector<bool>>& visited){
//收敛条件,找到
if(index==word.size()){
return true;
}
//终止条件,越界了
if(x<0||y<0||x>=board.size()||y>=board[0].size()) return false;
//访问过了则不访问,剪枝
if(visited[x][y]) return false;
//搜索到的字符与要求字符不相等,剪枝
if(board[x][y]!=word[index]) return false;
//执行到这里,说明当前字符与要求字符已经相等了
visited[x][y]=true;
//状态的扩展,搜索上下左右
bool res=DFS(board,word,x+1,y,index+1,visited)||DFS(board,word,x-1,y,index+1,visited)
||DFS(board,word,x,y-1,index+1,visited)||DFS(board,word,x,y+1,index+1,visited);
visited[x][y]=false;//退出
return res;
}
};