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
class Solution {
public:
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
vector<string> tmp;
vector<unordered_set<string> > current(2);
unordered_map<string, vector<string> > pre;
dict.erase(start);
current[0].insert(start);
dict.insert(end);
bool flag = false;
int left = 0;
int right = 1;
while(1)
{
for(auto iter = current[right].begin(); iter != current[right].end(); ++iter)
{
dict.erase(*iter);
}
left = !left;
right = !right;
for(auto iter = current[left].begin(); iter != current[left].end(); ++iter){
string cur = *iter;
for(int i = 0; i < cur.size(); i++)
{
string tmp = cur;
for(char a = 'a'; a < 'z'; a++)
{
if(a == cur[i])
continue;
tmp[i] = a;
if(tmp == end)
flag = true;
if(dict.find(tmp) != dict.end())
{
pre[tmp].push_back(cur);
current[right].insert(tmp);
}
}
}
}
current[left].clear();
if(current[right].size() == 0)
return results;
if(flag == true)
{
vector<string> temp;
buildResult(pre, temp, end);
return results;
}
}
return results;
}
private:
void buildResult(unordered_map<string, vector<string> > &pre,
vector<string> &result,
string word)
{
result.insert(result.begin(), word);
if(pre[word].size() == 0){
//vector<string> temp = result;
results.push_back(result);
return;
}
for(int i = 0; i < pre[word].size(); i++)
{
buildResult(pre, result, pre[word][i]);
result.erase(result.begin());
}
}
vector<vector<string> > results;
};
Round 2:
class Solution {
public:
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
if(start.empty() || end.empty())
return result;
dict.erase(start);
vector<string> cur;
cur.push_back(end);
unordered_map<string, unordered_set<string> > preMap;
unordered_set<string> bfs[2];
int flip = 0;
bool flag = false;
bfs[flip].insert(start);
while(!bfs[flip].empty())
{
for(auto i = bfs[flip].begin(); i != bfs[flip].end(); i++)
{
string cur = *i;
for(int x = 0; x < cur.size(); x++)
{
string temp = cur;
for(char j = 'a'; j <= 'z'; j++)
{
if(j == cur[x])
continue;
temp[x] = j;
if(temp == end)
{
flag = true;
}
if(dict.find(temp) != dict.end())
{
bfs[1-flip].insert(temp);
preMap[temp].insert(cur);
}
}
}
}
if(flag == true)
{
generateResult(end, preMap, cur);
return result;
}
for(auto i = bfs[1-flip].begin(); i != bfs[1-flip].end(); i++)
{
dict.erase(*i);
}
bfs[flip].clear();
flip = 1-flip;
}
return result;
}
private:
vector<vector<string> > result;
void generateResult(string end, unordered_map<string, unordered_set<string> > &preMap, vector<string> &cur)
{
if(preMap[end].size() == 0)
result.push_back(cur);
for(auto i = preMap[end].begin() ; i != preMap[end].end(); i++)
{
cur.insert(cur.begin(), *i);
generateResult(*i, preMap, cur);
cur.erase(cur.begin());
}
}
};