一、题目描述
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。
![](https://i-blog.csdnimg.cn/blog_migrate/69ebc549703dd77709398fa870875650.png)
示例 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
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/ju-zhen-zhong-de-lu-jing-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、运行结果
![](https://i-blog.csdnimg.cn/blog_migrate/6d926be591c187293c4a7242976c4989.png)
三、解题思路
整体思路:深度优先遍历(递归实现)
遍历输入字符数组中的每个字符,对每个字符都调用一次深度优先遍历(dfs),在dfs中执行如下操作:
递归出口:如果已经找到一条完整的路径(index >=word.length)返回true;如果下标越界或当前字符不匹配,就剪枝,结束当前路径查找,返回false;
如果当前字符匹配,则从四个方向分别进行递归查找,匹配下一个字符;
需要注意的是,不能重复使用数组中的字符,所以在一次递归遍历中,如果当前字符匹配,就将数组该位置的字符置为空格符,然后再向四个方向递归,结束当前递归后,再恢复数组中的该字符。
四、AC代码
class Solution {
public boolean exist(char[][] board, String word) {
int row = board.length;
int col = board[0].length;
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
boolean flag = dfs(board, word, i, j, 0); //从当前位置开始递归寻找
if(flag) //找到了一条完整的路径
return true;
}
}
return false;
}
// 递归遍历 i, j:数组的行和列索引,index:字符串中字符的索引
boolean dfs(char[][] board, String word, int i, int j, int index){
if(index >= word.length()) //已经找到一条完整路径
return true;
else if(i<0 || j<0 || i>=board.length || j>=board[0].length ||
board[i][j] != word.charAt(index))
return false;
board[i][j] = ' '; //防止被重复使用
// 向四个方向查找匹配下一个字符
boolean res = dfs(board, word, i+1, j, index+1)||dfs(board, word, i-1, j, index+1)
|| dfs(board, word, i, j-1, index+1) || dfs(board, word, i, j+1, index+1);
board[i][j] = word.charAt(index); //递归结束,恢复原来的字符
return res;
}
}