Leetcode中出现了两道词语阶梯的题目,大意是将一个词语将通过字典里面的词语,最终转换到目标词语,每次只能更改一个字符。两道题分别是求最少的转换次数和寻找最短的转换路径。词语阶梯是典型的BFS的题目,但是寻找转换路径的时候单纯的BFS会出现超时的问题,需要增加优化策略。优化策略是删除字典中BFS中上一层访问过的词语,因为它们如果出现在之后的BFS中,将不会是最短路径了。编程中通过unordered_set<string> visited,保存上一层BFS中访问过的词语。
Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, 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 length5.
Note:
- Return 0 if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
1 class Solution { 2 public: 3 int ladderLength(string start, string end, unordered_set<string> &dict) { 4 5 queue<string> q; 6 q.push(start); 7 unordered_set<string> visited; 8 visited.insert(start); 9 int depth = 1; 10 11 while (!q.empty()) { 12 for(string word : visited){ 13 dict.erase(word); 14 } 15 visited.clear(); 16 depth++; 17 int q_size = q.size(); 18 for (int i = 0; i < q_size; i++) { 19 string word = q.front(); 20 q.pop(); 21 22 for (int i = 0; i < word.size(); i++) { 23 string newWord = word; 24 for (char ch = 'a'; ch <= 'z'; ch++) { 25 newWord[i] = ch; 26 if(dict.count(newWord) == 0) continue; 27 if(newWord == end) return depth; 28 else{ 29 visited.insert(newWord); 30 q.push(newWord); 31 } 32 } 33 } 34 } 35 36 37 } 38 return 0; 39 } 40 };
Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from startto end, 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"]
Return
[ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
Note:
- All words have the same length.
- All words contain only lowercase alphabetic characters.
1 class Solution { 2 public: 3 vector<vector<string>> findLadders(string start, string end, 4 unordered_set<string> &dict) { 5 queue<vector<string>> q; 6 vector<string> path { start }; 7 q.push(path); 8 vector<vector<string>> res; 9 unordered_set<string> visited; 10 int level = 1, minLevel = INT_MAX; 11 while (!q.empty()) { 12 vector<string> path = q.front(); 13 q.pop(); 14 if (path.size() > level) { 15 for (string w : visited) 16 dict.erase(w); 17 visited.clear(); 18 level = path.size(); 19 if(level >= minLevel) break; 20 } 21 string word = path.back(); 22 for (size_t i = 0; i < word.size(); i++) { 23 string newWord = word; 24 for (char ch = 'a'; ch <= 'z'; ch++) { 25 newWord[i] = ch; 26 if (!dict.count(newWord)) continue; 27 if (newWord == end){ 28 path.push_back(newWord); 29 minLevel = path.size(); 30 res.push_back(path); 31 path.pop_back(); 32 break; 33 } else if (dict.count(newWord) 34 && find(path.begin(), path.end(), newWord) 35 == path.end()) { 36 visited.insert(newWord); 37 path.push_back(newWord); 38 q.push(path); 39 path.pop_back(); 40 } 41 } 42 } 43 } 44 return res; 45 } 46 };