leetcode-79-單詞搜索(用dfs解決)
題目描述:
給定一個二維網格和一個單詞,找出該單詞是否存在於網格中。
單詞必須按照字母順序,通過相鄰的單元格內的字母構成,其中“相鄰”單元格是那些水平相鄰或垂直相鄰的單元格。同一個單元格內的字母不允許被重復使用。
示例:
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)
說明:
1、這道題給定一個二維的vector,裏面存放著多個英文字符,還給了一個string,代表一個英文單詞。
要求判斷二維vector中存不存在一條路徑,連起來剛好就是string代表的單詞。
這條路徑不能使用重復的字符。
如果存在這樣一條路徑,那麽返回true,不存在就返回false。
2、這道題其實也就是深度優先搜索(DFS)的題目,熟悉這個算法的同學做這道題會很快。
我們還是照舊,舉個例子,大致說明一下思路。
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。
leetcode-79-單詞搜索(用dfs解決)