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:
- Only one letter can be changed at a time.
- Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
Note:
- Return 0 if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
- You may assume no duplicates in the word list.
- You may assume beginWord and endWord are non-empty and are not the same.
Example 1:
Input:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]
Output: 5
Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.
Example 2:
Input:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
Output: 0
Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.
题解:跟之前一样,只是只需求层数,我的方法是bfs然后用map记录每个点的层数,实际上可以在队列里面遍历q.size从而保证每次都是一层一层的进行,层数直接用一个变量维护即可。这里的最优解是用two-end 的bfs双端搜索,也就是每次从节点少的一端进行遍历,如果加入的队列集合节点数更少则更新遍历集,把之前的遍历集作为结果集,这里注意end不在字典的情况
代码:
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
int res = 1;
unordered_set<string> dict(wordList.begin(),wordList.end());
if(dict.count(endWord)==0) return 0;
unordered_set<string> set1 {beginWord};
unordered_set<string> set2 {endWord};
while (set1.size()) {
res++;
unordered_set<string> st;
for (auto word : set1) dict.erase(word);
for (auto word :set1) {
for (size_t i = 0; i < word.size(); ++i) {
string next = word;
for (char c = 'a'; c <= 'z'; ++c) {
next[i] = c;
if (dict.find(next) == dict.end()) continue;
if (set2.find(next) != set2.end()) {
return res;
}
st.insert(next);
}
}
}
set1 = st.size() < set2.size() ? st : set2;
set2 = st.size() < set2.size() ? set2 : st;
}
return 0;
}
};