Leetcode: Word Ladder II
Question
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.
Thoughts
1. preprocess the dictionary and build a graph. Adjacent nodes' distance is 1
2. using BFS iterator the graph
3. array father can record the father-son relation in iteration effectively
4. source code contains unordered_set, so when compiled under Linux system, extra flag must be used.
-std=c++11 or
-std=c++0x
code Runtime error. Can't figure out why...
#include <iostream>
#include <string>
#include <deque>
#include <vector>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>
using namespace std;
class Solution {
public:
vector<string> dct;
vector<int> graph[10010];
int father[10010];
int minDepth;
vector<vector<string> > res;
vector<string> party;
vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) {
res.clear(), party.clear();
dct.clear();
for(int i = 0; i < dict.size()+3; i ++) {
graph[i].clear();
father[i] = -3;
minDepth = -1;
}
if(dist(start, end) == 1) {
party.push_back(start), party.push_back(end);
res.push_back(party);
return res;
}
preprocess(dict);
deque<int> queue;
queue.clear();
for(int i = 0; i < dct.size(); i ++) {
if(dist(start, dct[i]) == 1) {
queue.push_back(i);
father[i] = -1;
//cout << i << endl;
}
}
while(!queue.empty()) {
int nextInt = queue.front();
queue.pop_front();
if(dist(end, dct[nextInt]) == 1) { // µÖ´ïÖÕµã, ´æ´¢Í˳ö
// handler otherwise
minDepth = assemble(party, nextInt, start, end);
res.push_back(party);
party.clear();
while(!queue.empty()) {
int finalInt = queue.front();
queue.pop_front();
if(dist(end, dct[nextInt]) == 1) {
if(assemble(party, finalInt, start, end) == minDepth) {
res.push_back(party);
party.clear();
}else{
return res;
}
}
}
return res;
}
for(int j = 0; j < graph[nextInt].size(); j ++) {
int candidate = graph[nextInt][j];
if(father[candidate] == -3) {
father[candidate] = nextInt;
queue.push_back(candidate);
}
}
}
}
int dist(const string &in, const string &ths) {
int dis = 0;
for(int i = 0; i < in.size() && dis < 2; i++) {
if(in[i] != ths[i])
dis ++;
}
return dis;
}
void preprocess(unordered_set<string> &dict) {
for(unordered_set<string>::iterator it1 = dict.begin(); it1 != dict.end(); it1 ++)
dct.push_back(*it1);
// ¹¹½¨ÁÚ½Ó±í
for(int i = 0; i < dct.size(); i ++) {
for(int j = 0; j < dct.size(); j ++) {
if(dist(dct[i], dct[j]) == 1) {
graph[i].push_back(j);
}
}
}
}
int assemble(vector<string> &party, const int &nextInt, const string &start, const string &end) {
party.push_back(end);
int pre = nextInt;
while(pre != -1 && pre >= 0) { //WA?
party.push_back(dct[pre]);
pre = father[pre];
}
party.push_back(start);
reverse(party.begin(), party.end());
return party.size();
}
};
int main() {
string start = "hot";
string end = "dog";
unordered_set<string> dict;
dict.insert("hot");
dict.insert("dog");
dict.insert("dot");
//dict.insert("lot");
//dict.insert("log");
Solution solution;
vector<vector<string> > res = solution.findLadders(start, end, dict);
for(int i = 0; i < res.size(); i ++) {
for(int j = 0; j < res[i].size(); j ++) {
cout << res[i][j] << " ";
}
cout << endl;
}
return 0;
}

浙公网安备 33010602011771号