题目描述:
给定一个二维网格和一个单词,找出该单词是否存在于网格中。算法
单词必须按照字母顺序,经过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不容许被重复使用。函数
示例:spa
board = [ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ] 给定 word = "ABCCED", 返回 true. 给定 word = "SEE", 返回 true. 给定 word = "ABCB", 返回 false.
要完成的函数:
bool exist(vector<vector<char>>& board, string word) code
说明:
一、这道题给定一个二维的vector,里面存放着多个英文字符,还给了一个string,表明一个英文单词。blog
要求判断二维vector中存不存在一条路径,连起来恰好就是string表明的单词。递归
这条路径不能使用重复的字符。索引
若是存在这样一条路径,那么返回true,不存在就返回false。string
二、这道题其实也就是深度优先搜索(DFS)的题目,熟悉这个算法的同窗作这道题会很快。io
咱们仍是照旧,举个例子,大体说明一下思路。class
board = [ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ]
给定的单词是SEE,那么咱们首先在矩阵中找到S,有两个,咱们先试第一个,明显第二个字母就对不上了,因而咱们进入对第二个的查找。
在第二个周围,咱们先试S上方的E,而后再在这个E的周围找另外一个E,明显没有。
因而咱们退一步,不试S上方的E了,咱们尝试S下方的E,能够,再在其附近找另外一个E,也找获得。
咱们在尝试的时候,要注意这个字符以前有没有使用过,这一步要作点处理。
从上述思路中,咱们能够知道要用循环+递归的方法来作这道题。
先用循环找到第一个字符的索引,而后进入递归,若是递归成功找到了,那么返回true。
若是不存在,那么再循环找第一个字符的下一个索引,而后一样进入递归,若是递归成功了,那么返回true。
若是仍是没有,那么再循环,一直循环,若是一直不知足,最后返回false。
代码以下(附详解):
bool dfs(vector<vector<char>>& board,int i,int j,string word,int index) { if(index==word.size())return true;//退出条件,知足了说明成功找到 int hang=board.size(),lie=board[0].size(); if(i>0)//尝试上方的字符 { if(board[i-1][j]==word[index]) { board[i-1][j]='!';//修改,避免重复使用 if(dfs(board,i-1,j,word,index+1))//再度进入递归 return true; board[i-1][j]=word[index];//修改回去 } } if(i<hang-1)//尝试下方的字符 { if(board[i+1][j]==word[index]) { board[i+1][j]='!'; if(dfs(board,i+1,j,word,index+1)) return true; board[i+1][j]=word[index]; } } if(j>0)//尝试左边的字符 { if(board[i][j-1]==word[index]) { board[i][j-1]='!'; if(dfs(board,i,j-1,word,index+1)) return true; board[i][j-1]=word[index]; } } if(j<lie-1)//尝试右边的字符 { if(board[i][j+1]==word[index]) { board[i][j+1]='!'; if(dfs(board,i,j+1,word,index+1)) return true; board[i][j+1]=word[index]; } } return false;//若是尝试四个方向都没能找到,返回false } bool exist(vector<vector<char>>& board, string word) { int hang=board.size(),lie=board[0].size(); for(int i=0;i<hang;i++) { for(int j=0;j<lie;j++) { if(board[i][j]==word[0])//找到第一个字符的索引 { board[i][j]='!';//修改board中这个索引的值,避免重复使用 if(dfs(board,i,j,word,1))//进入递归,若是返回true,那么找获得,最终返回true return true; board[i][j]=word[0];//若是递归没成功找到,那么把索引对应的字符给修改回去 } } } return false;//一直没能成功,说明不存在这样一条路径,返回false }
上述代码实测20ms,beats 94.50% of cpp submissions。