问题
给出两个单词(start和end)与一个字典,找出从start到end的最短转换序列的长度。规则如下:
- 一次只能改变一个字母
- 中间单词必须在字典里存在
例如:
给出
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
因为其中一条最短的转换序列为"hit" -> "hot" -> "dot" -> "dog" -> "cog",返回它的长度5。
注意
- 如果不存在转换序列,返回0
- 所有单词的长度一样
- 所有单词中只有小写字母
初始思路
有了单词梯II的分析,本题就很容易实现了。这里我们选择双vector的方案来进行改造。需要注意的几点:
- 只需要返回最短序列的长度,找到一个就可以返回了
- 同样由于只需返回长度,不需要像单词梯II那样每过一层才能把用过的单词去掉,使用一次就可以去除了。
- 每处理完一个vector表示一层处理结束,对当前序列长度加1
改造后的代码如下:


1 class Solution { 2 public: 3 int ladderLength(std::string start, std::string end, std::unordered_set<std::string> &dict) 4 { 5 std::vector<std::unordered_set<std::string>> candidates(2); 6 7 int current = 0; 8 int previous = 1; 9 int ladderLength = 1; 10 11 candidates[current].insert(start); 12 dict.erase(start); 13 14 while(true) 15 { 16 current = !current; 17 previous = !previous; 18 19 candidates[current].clear(); 20 21 for(auto iter = candidates[previous].begin(); iter != candidates[previous].end(); ++iter) 22 { 23 for(size_t pos = 0; pos < iter->size(); ++pos) 24 { 25 std::string word = *iter; 26 for(int i = 'a'; i <= 'z'; ++i) 27 { 28 if(word[pos] == i) 29 { 30 continue; 31 } 32 33 word[pos] = i; 34 35 if(dict.count(word) > 0) 36 { 37 if(word == end) 38 { 39 return ladderLength + 1; 40 } 41 42 candidates[current].insert(word); 43 dict.erase(word); 44 } 45 } 46 } 47 } 48 ++ladderLength; 49 50 if (candidates[current].size() == 0) 51 { 52 return 0; 53 } 54 } 55 56 return 0; 57 } 58 };
提交后一次通过Judge Small和Judge Large。