剑指 Offer 12. 矩阵中的路径 - 力扣(LeetCode)

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

思路:


  1. 标准矩阵搜索回溯模板 细节很多

复杂度:

宽松上界为 O(m n * 3L) L为字符串长度

题解:

class Solution {
public:
//两个函数,需要把第一个函数传入的内容定义为全局变量以便dfs函数调用
int ax[4]={0,0,1,-1},ay[4]={1,-1,0,0};//快速位移数组
vector<vector<char>> myboard;
string myword;
int n,m;
int check[10][10];//m n < 10


bool dfs(int x,int y,int k){
if(k==0)//这种写法不会将传入点记入check,需要手动实现
check[x][y]=1;
if(myword[k]!=myboard[x][y])//判定1 字母不同
return false;
if(k==myword.size()-1)//判定2 字母相同且长度完整
return true;
for(int i=0;i<4;i++){//四个方向 其实是三个不包含原来的
int rx=x+ax[i],ry=y+ay[i];
if(rx>=n||rx<0||ry>=m||ry<0||check[rx][ry])
continue;//剪枝

check[rx][ry]=1;//标记
bool res=dfs(rx,ry,k+1);//长度++
check[rx][ry]=0;//回溯
if(res)//只要有一条路成功即可
return true;
}
if(k==0)//无论在哪都要回溯回来
check[x][y]=0;
return false;
}
bool exist(vector<vector<char>>& board, string word) {
myboard=board;
myword=word;

n=board.size();
if(n==0) return false;//特判
m=board[0].size();

if(word.size()==0) return true;//特判
char start=word[0];//首字母
memset(check,0,sizeof(check));

for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(board[i][j]==start){//匹配首字母减少用时,不必要,在dfs中同样有,写的时候菜了
if(dfs(i,j,0))
return true;
}
}
}
return false;
}
};