leetcode-79-單詞搜索(用dfs解決)

題目描述:

給定一個二維網格和一個單詞,找出該單詞是否存在於網格中。算法

單詞必須按照字母順序,經過相鄰的單元格內的字母構成,其中「相鄰」單元格是那些水平相鄰或垂直相鄰的單元格。同一個單元格內的字母不容許被重複使用。函數

示例: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。

相關文章
相關標籤/搜索