Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord toendWord, such that:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the word list

For example,

Given:
beginWord = "hit"
endWord = "cog"
wordList = ["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,
            const unordered_set<string> &dict) {
        unordered_set < string > visited; // 判重
        unordered_map<string, vector<string> > father; //
        unordered_set<string> current, next; // 当前层,下一层,用集合是为了去重
        bool found = false;
        current.insert(start);
        visited.insert(start);
        while (!current.empty() && !found) {
            for (auto word : current){
                visited.insert(word);
            }
            for (auto word : current) {
                for (size_t i = 0; i < word.size(); ++i) {
                    string new_word = word;
                    for (char c = 'a'; c <= 'z'; ++c) {
                        if (c == new_word[i])
                            continue;
                        swap(c, new_word[i]);
                        if (new_word == end)
                            found = true; //找到了
                        if (visited.count(new_word) == 0
                                && (dict.count(new_word) || new_word == end)) {
                            next.insert(new_word);
                            father[new_word].push_back(word);
                        }
                        swap(c, new_word[i]); // restore
                    }
                }
            }
            current.clear();
            swap(current, next);
        }
        vector < vector<string> > result;
        if (found) {
            vector < string > path;
            buildPath(father, path, start, end, result);
        }
        return result;
    }
private:
    void buildPath(unordered_map<string, vector<string> > &father,
            vector<string> &path, const string &start, const string &word,
            vector<vector<string> > &result) {
        path.push_back(word);
        if (word == start) {
            result.push_back(path);
            reverse(result.back().begin(),result.back().end());
        } else {
            for (auto f : father[word]) {
                buildPath(father, path, start, f, result);
                path.pop_back();
            }
        }
    }
};

 

posted @ 2016-09-27 09:32  wxquare  阅读(205)  评论(0编辑  收藏  举报