126. Word Ladder II

問題:數組

給定StartWord和EndWord,在給定的dict中尋找每次值變換一個字母,最終從StartWord可以推移到EndWord的全部最短序列。bash

Example 1:
Input:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]
Output:
[
  ["hit","hot","dot","dog","cog"],
  ["hit","hot","lot","log","cog"]
]

Example 2:
Input:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
Output: []

Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.

  

解法1:函數

單向BFS找到路徑關係:spa

1.引入隊列q,保存每一步的全部展開結果。在每一步的結尾,用q去替換掉目標隊列queuecode

即從queue一次讀取,處理,將結果保存至q,再用q去替換掉queue。orm

2.每一次的處理:對象

首先從已經處理過獲得的新queue中的元素,從dict中刪除。(因爲獲得queue的方法,便是dict中存在,則保存至queue)blog

而後遍歷queue的每個word,進行如下處理:遞歸

對word的每個字符,進行a~z字母替換,隊列

判斷:1,若是==endWord,則標記found找到。同時記錄該路徑到children圖中。

         2,若是dict中存在,則加入新queue中(這裏是先保存到q,以後在總體和queue替換),同時記錄該路徑關係到children圖中。

 

構建children圖,key:A字符串,value:B字符串,(由A變化一個字符獲得多種可能的B)

unordered_map<string,vector<string>> children;
children[parent].push_back(child);

 

再經過children圖進行DFS,構建全部path結果數組。

 1         vector<string> path={beginWord};
 2         if(found){
 3             getPath(children, beginWord, endWord, path, res);
 4         }

DFS 遞歸函數:

 1     void getPath(unordered_map<string,vector<string>>& children, string beginWord, string endWord, vector<string>& path, vector<vector<string>>& res) {
 2         if(beginWord==endWord){
 3             res.push_back(path);
 4             return;
 5         }
 6         const auto find = children.find(beginWord);
 7         if(find==children.end()) return;
 8         for(const string child: find->second){
 9             path.push_back(child);
10             getPath(children, child, endWord, path, res);
11             path.pop_back();
12         }
13     }

 

解法2:

diff解法1: 

雙向 查找路徑關係。每次選取size最短的做爲對象,進行展開查找。

將解法1中的對象隊列queue,改成q1和q2,

若q1短,那麼本次將q1看做queue,q2看做endWord,反之亦然。

所作處理皆同方法1,

只有children的構建,因爲雙向構建,正向處理的狀況下,children構建方法同解法1,

反向處理(由endWord向start推)的狀況下,parent和child對掉。

要斷定是否爲正向,則須要引入變量 backward。

代碼參考:

解法1:

 1 class Solution {
 2 public:
 3     void getPath(unordered_map<string,vector<string>>& children, const string beginWord, const string endWord, vector<string>& path, vector<vector<string>>& res) {
 4         if(beginWord==endWord){
 5             res.push_back(path);
 6             return;
 7         }
 8         auto find=children.find(beginWord);
 9         if(find==children.end()) return;
10         for(const string& child:find->second){
11             path.push_back(child);
12             getPath(children, child, endWord, path, res);
13             path.pop_back();
14         }
15     }
16     
17     vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
18         vector<vector<string>> res;
19         unordered_set<string> dict(wordList.begin(), wordList.end());
20         unordered_set<string> queue={beginWord}, p;
21         unordered_map<string,vector<string>> children;
22         bool found=false;
23         if(dict.count(endWord)==0)return res;
24         while(!queue.empty()&&!found){
25             for(const string& word: queue){
26                 dict.erase(word);
27             }
28             for(const string& word: queue){
29                 string cur=word;
30                 for(int j=0; j<=word.length(); j++){
31                     char ch=cur[j];
32                     for(char i='a'; i<='z'; i++){
33                         cur[j]=i;
34                         if(cur==endWord){
35                             found=true;
36                             children[word].push_back(cur);
37                         }else if(dict.count(cur)&&!found){
38                             p.insert(cur);//下一次待檢索
39                             children[word].push_back(cur);
40                         }
41                     }
42                     cur[j]=ch;
43                 }
44             }
45             swap(queue,p);
46             p.clear();
47         }
48         vector<string> path={beginWord};
49         if(found){
50             getPath(children, beginWord, endWord, path, res);
51         }
52         return res;
53     }
54 };

解法2:

 1 class Solution {
 2 public:
 3     void getPath(unordered_map<string,vector<string>>& children, string beginWord, string endWord, vector<string>& path, vector<vector<string>>& res) {
 4         if(beginWord==endWord){
 5             res.push_back(path);
 6             return;
 7         }
 8         const auto find = children.find(beginWord);
 9         if(find==children.end()) return;
10         for(const string child: find->second){
11             path.push_back(child);
12             getPath(children, child, endWord, path, res);
13             path.pop_back();
14         }
15     }
16     vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
17         vector<vector<string>> res;
18         unordered_set<string> dict(wordList.begin(), wordList.end());
19         unordered_set<string> q1={beginWord}, q2={endWord};
20         bool backward=false;
21         unordered_map<string,vector<string>> children;
22         bool found=false;
23         if(dict.count(endWord)==0)return res;
24         while(!q1.empty()&&!q2.empty()&&!found){
25             if(q1.size()>q2.size()){
26                 backward=!backward;
27                 swap(q1,q2);
28             }
29             for(const string& word: q1){
30                 dict.erase(word);
31             }
32             for(const string& word: q2){
33                 dict.erase(word);
34             }
35             unordered_set<string> q;
36             for(const string& word: q1){
37                 string cur=word;
38                 for(int j=0; j<=word.length(); j++){
39                     char ch=cur[j];
40                     for(char i='a'; i<='z'; i++){
41                         cur[j]=i;
42                         if(q2.count(cur)){
43                             found=true;
44                             if(!backward){
45                                 children[word].push_back(cur);
46                             }else{
47                                 children[cur].push_back(word);
48                             }
49                         }else if(dict.count(cur)&&!found){
50                             q.insert(cur);//下一次待檢索
51                             if(!backward){
52                                 children[word].push_back(cur);
53                             }else{
54                                 children[cur].push_back(word);
55                             }
56                         }
57                     }
58                     cur[j]=ch;
59                 }
60             }
61             swap(q1,q);
62             q.clear();
63         }
64         vector<string> path={beginWord};
65         if(found){
66             getPath(children, beginWord, endWord, path, res);
67         }
68         return res;
69     }
70 };
相關文章
相關標籤/搜索