/**********************************************************************************************************
当题目看不出任何规律,既不能用分治,贪心,也不能用动规时,这时候万能方法——搜就
派上用场了。搜索分为广搜和深搜,广搜里面又有普通广搜,双向广搜, A* 搜索等。深搜里面又有普通深搜,回溯法等。
广搜和深搜非常类似(除了在扩展节点这部分不一样),二者有相同的框架,如何表示状
如何扩展状态?如何判重?尤其是判重,解决了这个问题,基本上整个问题就解决了。
描述
Given two words (start and end), and a dictionary, find the length of shortest transformation sequence
from start to end, such that:
• Only one leer 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.**********************************************************************************************************/
class Solution{
public:
typedef string state_t;
int ladderLength(string start, string end, const unordered_set<string> &dict){
if (start.size() != end.size()) return 0;
if (start.empty() || end.empty()) return 0;
queue<string > next, current;// 下一层 ,当前层
unordered_set<string> visited; //判断重复
int level = 0;
unordered_map<string, string> father;
bool found = false;
current.push(start);
while (!current.empty() && !found){
++level;
while (!current.empty() && !found){
const string str(current.front());
current.pop();
for (size_t i = 0; i < str.size(); i++){
string new_word(str);
for (char c = 'a'; c < 'z'; c++){ //start = "hit"
if (c == new_word[i]) continue;
swap(c, new_word[i]);
if (new_word == end){
found = true;
father[new_word] = str;//??
}
if (dict.count(new_word) > 0 && !visited.count(new_word)){
next.push(new_word);
visited.insert(new_word);
father[new_word] = str;
}
swap(c, new_word[i]);
}
}
}
swap(next, current);
}
if (found) return level + 1;
else return 0;
}
};
参考资料:
LeetCode题解