第二天 回溯部分刷起
简单回顾一下回溯:
1.回溯一般用在广搜和深搜中,一种暴力搜索。
2.回溯的过程就是撤销前一次答案,并加入下一次的答案的过程;
3.撤销的原则一般是一对一的,即前一次加入答案后面就撤销一次答案,但不同写法不同,具体参考上一篇:
关于是否需要回溯这件事_追求决定高度的博客-CSDN博客https://blog.csdn.net/qq_57328462/article/details/124803641?spm=1001.2014.3001.5502此题中规中矩,只需要注意 查找的位置 不是给定的,需要自己去寻找。
代码:
class Solution {
public:
bool flag=false;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
void backtracking(vector<vector<char>>& board, string &word,vector<vector<int>>& used,string &s,int x,int y)//确定函数返回值、参数
{
if(s==word)//结束条件
{
flag=true;
return;
}
for(int i=0;i<4;i++)//前进条件
{
int sx=x+dx[i];
int sy=y+dy[i];
if(sx<0||sx>board.size()-1||sy<0||sy>board[0].size()-1||used[sx][sy]==1||board[sx][sy]!=word[s.size()])
continue;
s.push_back(board[sx][sy]);
used[sx][sy]=1;
backtracking(board,word,used,s,sx,sy);
used[sx][sy]=0;
s.pop_back();
}
return ;
}
bool exist(vector<vector<char>>& board, string word)
{
int row=board.size();
int col=board[0].size();
if(row*col<word.size())return false;
vector<vector<int>>used(row,vector<int>(col,0));
string s;
for(int i=0;i<board.size();i++)
{
for(int j=0;j<board[0].size();j++)
{
if(board[i][j]==word[0])
{
used[i][j]=1;
s.push_back(board[i][j]);
backtracking(board,word,used,s,i,j);
if(flag)
break;
else
{
s.pop_back();
used[i][j] = 0;
}
}
}
if(flag)break;
}
return flag;
}
};
ps:因为回溯是需要用到递归的,因此 写法上利用递归三部曲完成:
1.确定函数返回值及参数;
2.确定终止条件;
3.前进逻辑;
本题 用到了两次回溯逻辑分别是:
一、在寻找搜索的起始位置时 【将第一个元素单独考虑】
二、内部元素进行递归调用时