回溯法解决力扣79题单词搜索
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-search
class Solution {
public:
//方便进行上下左右方向的遍历
int dir[4][2]={
{1 ,0},
{-1,0},
{0, 1},
{0,-1}
};
bool exist(vector<vector<char>>& board, string word) {
if(board.size()==0)
return false;
bool find=false;
int w=board.size(),h=board[0].size();
vector<vector<bool> > arrived(w,vector<bool>(h,false));
for(int i=0;i<w;i++){
for(int k=0;k<h;k++){//每一个点都有可能是起点
backtracking(i,k,arrived,0,word,board,find);
}
}
return find;
}
void backtracking(int x,int y,vector<vector<bool> > &arrived,int arriv,string &word,vector<vector<char>>& board,bool &find) {//数组必须使用&,避免空间使用过多
if(x < 0|| y<0 || x>=board.size() || y>=board[0].size()||arrived[x][y]){
return;
}
if(word[arriv]!=board[x][y]||find)
return;
//将不满足条件的情况剔除,确认(x,y)可以作为遍历点
if(arriv==word.size()-1){
find=true;
return;
}
arrived[x][y]=true;//采用回溯法,遍历后设为false,保证其他遍历可以遍历该点
for(int i=0;i<4;i++){//对上下左右遍历
int x_=x+dir[i][0];
int y_=y+dir[i][1];
backtracking(x_,y_,arrived,arriv+1,word,board,find);
}
arrived[x][y]=false;
}
};
解析:
对任意位置搜索后,我们需要将该位置标记(arrived[x][y]=true)以防止重复遍历该位置,当该深度搜索完成后,我们再将该位置的标记取消(arrived[x][y]=false)避免干扰。