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 {
vector<string> vdict;
vector<vector<int> > adj;
void build(unordered_set<string> &dict){
int i, j;
vdict.clear();
unordered_map<string, int> ids;
for(auto it=dict.begin(); it != dict.end(); it++){
ids[*it] = vdict.size();
vdict.push_back(*it);
}
adj.clear();
adj.resize(vdict.size());
for(int i = 0; i < vdict.size(); i++){
string w = vdict[i];
for(int j = 0; j < vdict[i].size(); j++){
for(char c = 'a'; c <= 'z'; c++)
if(c != vdict[i][j]){
w[j] = c;
if(ids.count(w)){
adj[i].push_back(ids[w]);
}
w[j] = vdict[i][j];
}
}
}
}
void gen(int v1, int v2, vector<vector<int> >& prev, vector<int>& path, vector<vector<string> >&ans){
path.push_back(v2);
if(v2 == v1 and path.size() > 1){
ans.push_back(vector<string>());
for(auto rit = path.rbegin(); rit != path.rend(); rit++){
ans.back().push_back(vdict[*rit]);
}
}else{
int i;
for(i = 0; i < prev[v2].size(); i++){
gen(v1, prev[v2][i], prev, path, ans);
}
}
path.pop_back();
}
public:
vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
dict.insert(start);
dict.insert(end);
build(dict);
queue<int> que;
vector<vector<int> > prev(vdict.size());
vector<int> distance(vdict.size());
int v, v1, v2;
for(v1 = 0; vdict[v1] != start; v1++);
for(v2 = 0; vdict[v2] != end; v2++);
for(int i = 0; i < adj[v1].size(); i++){
v = adj[v1][i];
que.push(v);
prev[v].push_back(v1);
distance[v] = 1;
}
while(not que.empty()){
int v1 = que.front(); que.pop();
if(v1 == v2) break;
int d = distance[v1] + 1;
for(int i = 0; i < adj[v1].size(); i++){
v = adj[v1][i];
if(prev[v].size() == 0){
prev[v].clear();
prev[v].push_back(v1);
distance[v] = d;
que.push(v);
}else if(distance[v] == d){
prev[v].push_back(v1);
}
}
}
vector<vector<string> > ans;
vector<int> path;
gen(v1, v2, prev, path, ans);
return ans;
}
};
http://discuss.leetcode.com/questions/1051/word-ladder-ii