给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。
示例 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
解题思路:
可以用深度优先遍历,从第一个字母开始遍历二维数组,找到第一个单词字母,然后先往一个方向搜索到底,如果不对再返回上一个元素,换另一个方向搜索,和图的深度优先遍历类似,用递归实现。如果字母全部匹配成功就返回真,其他则返回假,字母匹配成功则把该位置变为空,防止重复访问,在四个方向重复此运算(用递归),返回之前把该位置的值恢复。
算法流程:
public:
1.把二维数组的行数赋给变量line,列数赋给变量row
2.从二维数组的左上角第一个元素开始遍历整个二维数组,如果dfs函数从该元素开始匹配单词word成功,则返回true
3.返回false
private:
1.声明行数line,和列数row
2.定义dfs函数,传入二维数组,单词,行数 i,列数 j,单词字母的索引 k
如果 i 越界或 j 越界或单词字母不匹配
返回false
如果匹配成功
返回true
把此位置变为空
定义布尔变量res=四个方向上的递归的或(只要有一个匹配成功就行)
把该位置的值恢复
返回res
代码:
class Solution {
public:
bool exist(vector<vector<char>>& board, string word) {
line=board.size();
row=board[0].size();
for(int i=0;i<line;i++) {
for(int j=0;j<row;j++) {
if(dfs(board,word,i,j,0))
return true;
}
}
return false;
}
private:
int line,row;
bool dfs(vector<vector<char>>& board,string word,int i,int j,int k) {
if(i>=line||i<0||j>=row||j<0||
board[i][j]!=word[k])
return false;
if(k==word.size()-1)
return true;
board[i][j]='\0';
bool res=
dfs(board,word,i+1,j,k+1)||
dfs(board,word,i-1,j,k+1)||
dfs(board,word,i,j+1,k+1)||
dfs(board,word,i,j-1,k+1);
board[i][j]=word[k];
return res;
}
};
运行步骤:
(只考虑正确路径)
i=0,j=0,k=0,word.size()-1=5
dfs(board,word ,0,0,0),board[0][0]='\0',
dfs(board,word ,0,1,1),board[0][1]='\0',
dfs(board,word ,0,2,2),board[0][2]='\0',
dfs(board,word ,1,2,3),board[1][2]='\0',
dfs(board,word ,2,2,4),board[2][2]='\0',
dfs(board,word ,2,1,5),board[2][1]='\0',
k=word.size()-1=5,返回true
dfs(board,word ,2,1,5),board[2][1]='D',
返回true
dfs(board,word ,2,2,4),board[2][2]='E',
返回true
dfs(board,word ,1,2,3),board[1][2]='C',
返回true
dfs(board,word ,0,2,2),board[0][2]='C',
返回true
dfs(board,word ,0,1,1),board[0][1]='B',
返回true
dfs(board,word ,0,0,0),board[0][0]='A',
返回true
if(true)
返回true