题目:
给定一个m x n 二维字符网格board 和一个字符串单词word 。如果word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)。
url:https://leetcode.cn/problems/ju-zhen-zhong-de-lu-jing-lcof/
示例 1:
输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true
示例 2:
输入:board = [[“a”,“b”],[“c”,“d”]], word = “abcd”
输出:false
提示:
1 <= board.length <= 200
1 <= board[i].length <= 200
board 和 word 仅由大小写英文字母组成
做此题之前最好看一下 视频讲解
这个迷宫问题跟这个题很类似
首先了解递归的本质,递归的本质是栈,
递归每进去一次都会新开辟一个栈空间,可以看到输入test(4),进去后n>2,所以进入了test(3),这个时候其实是新的栈空间,每次栈空间内都会存放有n,就是4的那个栈内存放的n为4, 3那个栈内存放的n为3,输出时候并不会先输出4,因为栈是现金后出的,最后n为2的时候,不满足继续递归的条件了,这个时候会优先输出最后执行的函数,也就是2的那个栈空间,这时候打印出n=2,然后继续抛出栈顶的元素,这时候抛出3的那个栈,这个栈内存放的是n=3,一定要注意,每个栈空间内,存放的数据都是独立的,记录着进入时的状态。
然后看这道题,
迷宫问题就是,有墙阻拦,踩踏过的点不用在踩了,这个其实也一样,不满足连续word的地方也可以理解为一堵墙,大神思路:https://leetcode.cn/problems/ju-zhen-zhong-de-lu-jing-lcof/solution/mian-shi-ti-12-ju-zhen-zhong-de-lu-jing-shen-du-yo/这个里面那个ppt很生动形象
public bool Exist(char[][] board, string word) {
int k = 0;
for(int i = 0; i< board.Length;i++) //开始遍历数组,找第一个字母
{
for(int j = 0;j<board[0].Length;j++)
{
//从起点0,0出发
if( dfs(board,word,i,j,k) )return true;
//为真才返回true,若为假,也不返回false,接着遍历,找第一个点
}
}
return false;
}
public bool dfs(char[][] board,string word,int i,int j,int k)
{
//超过边界了直接返回false,如果当前矩阵所在位置的元素跟单词目前的不一样,直接返回
if(i>board.Length-1 || i<0 || j>board[0].Length-1 || j<0 || board[i][j]!=word[k])
{
return false;
}
//如果当前相同,且已经完全匹配,返回true
if(k == word.Length - 1) return true; //字符串匹配完成
/*
//为什么要标记,因为要表示这个节点已经走过了,
例如
上图的ABCE,走过A,再去检查S,发现字符不一样,dfs(board,word,i+1,j,k+1) 直接返回了false,就去检查dfs(board,word,i,j+1,k+1) B,
发现字符一样不越界,那么就检查B的下 右 上 左,总不能再去往左边检查A吧,那么就绕回去了,要知道,
每进一次栈,数据都存了一份当前的副本,进入B的时候,B内记录的有board[i][j] = '\0' ,就是B暂时变为 '\0',代表走过了,
同时每个栈内记录了word[k],是进入那个栈时候的word[k],即记录board[i][j] 其实原本放的是B,以后下面万一哪一步一路没走通(打比方),
需要回到A回来从其他路开始走的时候,比如以前是从A往下到S,从S走到最后比如F,发现不行,走不通,这个时候你要给F和B和A变回他们当初的样子的,
他们不是'\0',他们最初的数字被存放在他们自己的栈内,就是word[k]。
*/
board[i][j] = '\0' ; //标志为:本次已经遍历过了
bool res = dfs(board,word,i+1,j,k+1) || dfs(board,word,i,j+1,k+1)
|| dfs(board,word,i-1,j,k+1) || dfs(board,word,i,j-1,k+1);
//下 右 上 左
board[i][j] = word[k]; //还原原来位置应该是什么
return res;
}