Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:code
Only one letter can be changed at a time
Each intermediate word must exist in the word list
For example,orm
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.隊列
Note:
Return 0 if there is no such transformation sequence.
All words have the same length.
All words contain only lowercase alphabetic characters.字符串
註釋部分提出來:string
// 26叉樹廣度優先遍歷,找到end,或者是樹沒法繼續延伸 // 樹的延伸是基於當前的字符串,每次變化一個字符[a-z] // 若是新的字符串在wordlist裏就加入候選和延伸隊列裏 // 因爲是廣度遍歷,第一次找到的候選必定是最短路徑的所以 // 能夠將找到的候選從dict裏刪除,避免後續再找到的時候造成死循環 // 要計算是第幾層,用一個空字符串來做爲層之間的分隔符
這裏最坑的地方是標準答案不是求的轉移次數,而是求的轉移鏈的鏈長度,也就是轉移一次的狀況,長度是2,其餘相似的都是大了一。白白耗費了好多時間......it
耗時:263msio
class Solution { public: // 26叉樹廣度優先遍歷,找到end,或者是樹沒法繼續延伸 // 樹的延伸是基於當前的字符串,每次變化一個字符[a-z] // 若是新的字符串在wordlist裏就加入候選和延伸隊列裏 // 因爲是廣度遍歷,第一次找到的候選必定是最短路徑的所以 // 能夠將找到的候選從dict裏刪除,避免後續再找到的時候造成死循環 // 要計算是第幾層,用一個空字符串來做爲層之間的分隔符 int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) { if (beginWord == endWord) { return 0; } if (beginWord.length() == 0) { return 0; } wordList.erase(beginWord); deque<string> q; int step = 2; q.push_back(beginWord); q.push_back(""); while (!q.empty()) { string s = q.front(); q.pop_front(); if (s == "") { if (q.empty()) { return 0; } q.push_back(""); step++; continue; } //cout << "s=" << s << endl; for (int w_i = 0; w_i < s.length(); w_i++) { char ch = s[w_i]; for (char ch_i = 'a'; ch_i <= 'z'; ch_i++) { if (ch_i == ch) { continue; } s[w_i] = ch_i; if (s == endWord) { //cout << "find s=" << s << endl; return step; } if (wordList.find(s) != wordList.end()) { q.push_back(s); wordList.erase(s); //cout << "new s=" << s << endl; } s[w_i] = ch; } } } return 0; } };