您的位置:首页 > 其它

[LeetCode] Word Ladder II

2015-07-03 16:05 288 查看
This is a tough problem! I read some solutions from the web. This link provides a one-end BFS solution. The code is reorganized as follows.

class Solution {
public:
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
dict.insert(end);
unordered_set<string> current;
unordered_set<string> next;
current.insert(start);
ladder.push_back(end);
while (true) {
for (string cur : current)
dict.erase(cur);
for (string cur : current)
findChildren(cur, next, dict);
if (next.empty()) return ladders;
if (next.find(end) != next.end()) {
genLadders(start, end);
return ladders;
}
current.clear();
swap(current, next);
}
}
private:
unordered_map<string, vector<string> > ancestors;
vector<string> ladder;
vector<vector<string> > ladders;

void findChildren(string& word, unordered_set<string>& next, unordered_set<string>& dict) {
int len = word.length();
string ancestor = word;
for (int p = 0; p < len; p++) {
char letter = word[p];
for (int i = 0; i < 26; i++) {
word[p] = 'a' + i;
if (dict.find(word) != dict.end()) {
next.insert(word);
ancestors[word].push_back(ancestor);
}
}
word[p] = letter;
}
}

void genLadders(string& start, string& end) {
if (start == end) {
reverse(ladder.begin(), ladder.end());
ladders.push_back(ladder);
reverse(ladder.begin(), ladder.end());
return;
}
for (string ancestor : ancestors[end]) {
ladder.push_back(ancestor);
genLadders(start, ancestor);
ladder.pop_back();
}
}
};


This link shares a two-end BFS solution, which is much faster! I have also rewritten that code below.

class Solution {
public:
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
vector<string> ladder;
vector<vector<string> > ladders;
ladder.push_back(start);
unordered_set<string> startWords;
unordered_set<string> endWords;
startWords.insert(start);
endWords.insert(end);
unordered_map<string, vector<string> > children;
bool flip = true;
if (searchLadders(startWords, endWords, children, dict, ladder, ladders, flip))
genLadders(start, end, children, ladder, ladders);
return ladders;
}
private:
bool searchLadders(unordered_set<string>& startWords, unordered_set<string>& endWords,
unordered_map<string, vector<string> >& children, unordered_set<string>& dict,
vector<string>& ladder, vector<vector<string> >& ladders, bool& flip) {
flip = !flip;
if (startWords.empty()) return false;
if (startWords.size() > endWords.size())
return searchLadders(endWords, startWords, children, dict, ladder, ladders, flip);
for (string word : startWords) dict.erase(word);
for (string word : endWords) dict.erase(word);
unordered_set<string> intermediate;
bool done = false;
for (string word : startWords) {
string temp = word;
int len = word.length();
for (int p = 0; p < len; p++) {
char letter = word[p];
for (int i = 0; i < 26; i++) {
word[p] = 'a' + i;
if (endWords.find(word) != endWords.end()) {
done = true;
flip ? children[word].push_back(temp) : children[temp].push_back(word);
}
else if (!done && dict.find(word) != dict.end()) {
intermediate.insert(word);
flip ? children[word].push_back(temp) : children[temp].push_back(word);
}
}
word[p] = letter;
}
}
return done || searchLadders(endWords, intermediate, children, dict, ladder, ladders, flip);
}
void genLadders(string& start, string& end, unordered_map<string, vector<string> >& children,
vector<string>& ladder, vector<vector<string> >& ladders) {
if (start == end) {
ladders.push_back(ladder);
return;
}
for (string child : children[start]) {
ladder.push_back(child);
genLadders(child, end, children, ladder, ladders);
ladder.pop_back();
}
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: