Given two words (beginWord and endWord), and a dictionary, find the length of shortest transformation sequence from beginWord to endWord, such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the dictionary
For example,
Given:
start = "hit"
end = "cog"
dict = ["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.
题目这么长感觉会被吓到,其实这题是典型的广度搜索,为什么用广搜,因为他要求“最短”变换长。每次变一个字母,也就是说每个字母的变换方式决定了那一层的节点数,我们可以一层一层的搜,直到搜到某一层的某个变换刚好是endWord 那么流程结束,因为是一层一层扩占所以保证了结果的最小性。 广搜是最合适的方案。
int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) { int length = 1; if (beginWord == endWord) { return length; } queue<string> q; queue<string> t; unordered_set<string> checked; q.push(beginWord); while (!q.empty()) { string topWord = q.front(); q.pop(); for (int i = 0; i < topWord.length(); i++) { for (char c = 'a'; c <= 'z'; c++) { string newWord = topWord; newWord.replace(i, 1, string(1, c)); if (newWord == endWord) { return length + 1; } if (checked.find(newWord) == checked.end() && wordDict.find(newWord) != wordDict.end()) { t.push(newWord); checked.insert(newWord); } } } if (q.empty()) { length++; swap(q, t); } } return 0; }
这里值得一提的trick 是交替使用两个队列,每当一个为空的时候,说明结束了一层的搜索,所以length需要加1,然后使用swap 来将两个队列交换。