参考链接
http://www.cnblogs.com/x1957/p/3274819.html
http://www.cnblogs.com/x1957/p/3526838.html
题目描述
Word Ladder
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 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.
Word Ladder II
Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) 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"]
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.
题目分析
I 思路应该是按层遍历,字典中与某个单词只有一个字母之差的都是这个字母的孩子,构建一棵树,再按层遍历,遍历到目标单词时的层数就是转换次数。
II 需要记录每一个孩子的父亲结点,注意的事,父亲不只有一个。
总结
代码示例
int ladderLength(string start, string end, unordered_set<string> &dict) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(start.size() != end.size()) return 0;
if(start.empty() || end.empty())return 0;
queue<string> path;
path.push(start);
int level = 1;
int count = 1;
dict.erase(start);
while(dict.size() > 0 && !path.empty())
{
string curword = path.front();
path.pop();count--;
for(int i = 0; i < curword.size(); i++)
{
string tmp = curword;
for(char j='a'; j<='z'; j++)
{
if(tmp[i]==j)continue;
tmp[i] = j;
if(tmp==end)return level+1;
if(dict.find(tmp) != dict.end()) path.push(tmp);
dict.erase(tmp);
}
}
if(count==0)
{
count = path.size();
level++;
}
}
return 0;
}
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
if(start == end) return 1;
queue<string > que;
map<string , int> dist;
dist[start] = 0;
que.push(start);
while(!que.empty()){
string top = que.front();que.pop();
for(int i = 0 ; i < top.length() ; i++){
for(int j = 'a' ; j <= 'z' ; j++){
if(j != top[i]){
string next = top;
next[i] = j;
if(next == end){
return dist[top] + 2;
}
if(dict.find(next) != dict.end() && dist.find(next) == dist.end()){
dist[next] = dist[top] + 1;
que.push(next);
}
}
}
}
}
return 0;
}
};
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
if(start == end) return 1;
queue<string > que;
map<string , int> dist;
dist[start] = 0;
que.push(start);
while(!que.empty()){
string top = que.front();que.pop();
for(int i = 0 ; i < top.length() ; i++){
for(int j = 'a' ; j <= 'z' ; j++){
if(j != top[i]){
string next = top;
next[i] = j;
if(next == end){
return dist[top] + 2;
}
if(dict.find(next) != dict.end() && dist.find(next) == dist.end()){
dist[next] = dist[top] + 1;
que.push(next);
}
}
}
}
}
return 0;
}
};
class Solution {
public:
vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict)
{
result_.clear();
unordered_map<string, vector<string>> prevMap;
for(auto iter = dict.begin(); iter != dict.end(); ++iter)
prevMap[*iter] = vector<string>();
vector<unordered_set<string>> candidates(2);
int current = 0;
int previous = 1;
candidates[current].insert(start);
while(true)
{
current = !current;
previous = !previous;
for (auto iter = candidates[previous].begin(); iter != candidates[previous].end(); ++iter)
dict.erase(*iter);
candidates[current].clear();
for(auto iter = candidates[previous].begin(); iter != candidates[previous].end(); ++iter)
{
for(size_t pos = 0; pos < iter->size(); ++pos)
{
string word = *iter;
for(int i = 'a'; i <= 'z'; ++i)
{
if(word[pos] == i)continue;
word[pos] = i;
if(dict.count(word) > 0)
{
prevMap[word].push_back(*iter);
candidates[current].insert(word);
}
}
}
}
if (candidates[current].size() == 0)
return result_;
if (candidates[current].count(end)) break;
}
vector<string> path;
GeneratePath(prevMap, path, end);
return result_;
}
private:
void GeneratePath(unordered_map<string, vector<string>> &prevMap, vector<string>& path, const string& word)
{
if (prevMap[word].size() == 0)
{
path.push_back(word);
vector<string> curPath = path;
reverse(curPath.begin(), curPath.end());
result_.push_back(curPath);
path.pop_back();
return;
}
path.push_back(word);
for (auto iter = prevMap[word].begin(); iter != prevMap[word].end(); ++iter)
GeneratePath(prevMap, path, *iter);
path.pop_back();
}
vector<vector<string>> result_;
};
class Solution {
public:
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
vector<vector<string> >ans;
if(start == end) return ans;
unordered_set<string>current , next;
unordered_set<string> flag;
unordered_map<string,vector<string> > father;
current.insert(start);
bool found = false;
while(!current.empty() && !found) {
//expand
for(const auto &x : current) {
flag.insert(x);
}
for(auto x : current) {
for(int i = 0 ; i < x.size() ; ++i) {
for(int j = 'a' ; j <= 'z' ; ++j) {
if(x[i] == j) continue;
string tmp = x;
tmp[i] = j;
if(tmp == end) found = true;
if(dict.find(tmp) != dict.end() && flag.find(tmp) == flag.end()) {
next.insert(tmp);
father[tmp].push_back(x);
}
}
}
}
//end expand
current.clear();
swap(current, next);
}
//start foudn father
if(found) {
vector<string> c;
dfs(ans , father , c , start , end);
}
return ans;
}
private:
void dfs(vector<vector<string> >&ans,
unordered_map<string,vector<string> >& father ,
vector<string>& c ,
string& start ,
string& now) {
c.push_back(now);
if(now == start) {
ans.push_back(c);
reverse(ans.back().begin() , ans.back().end());
c.pop_back();
return;
}
auto que = father.find(now) -> second;
for(auto& x : que) {
dfs(ans , father , c , start , x);
}
c.pop_back();
}
};
推荐学习C++的资料
C++标准函数库
在线C++API查询
map使用方法
queue使用方法
vector使用方法