zoukankan      html  css  js  c++  java
  • [LeetCode] word ladder II

    http://www.lintcode.com/zh-cn/problem/word-ladder-ii/#

    给出两个单词(start和end)和一个字典,找出所有从start到end的最短转换序列

    比如:

    1. 每次只能改变一个字母。
    2. 变换过程中的中间单词必须在字典中出现。

    样例

    给出数据如下:

    start = "hit"

    end = "cog"

    dict = ["hot","dot","dog","lot","log"]

    返回

    [

        ["hit","hot","dot","dog","cog"],

        ["hit","hot","lot","log","cog"]

      ]

    注意

    • 所有单词具有相同的长度。
    • 所有单词都只包含小写字母。
    // Solution
    //
    //      1) Using BSF algorithm build a graph like below
    //      2) Using DSF to parse the tree to the transformation path.
    //
    // For example:
    //
    //     start = "hit"
    //     end = "cog"
    //     dict = ["hot","dot","dog","lot","log","dit","hig", "dig"]
    //
    //                      +-----+
    //        +-------------+ hit +--------------+
    //        |             +--+--+              |
    //        |                |                 |
    //     +--v--+          +--v--+           +--v--+
    //     | dit |    +-----+ hot +---+       | hig |
    //     +--+--+    |     +-----+   |       +--+--+
    //        |       |               |          |
    //        |    +--v--+         +--v--+    +--v--+
    //        +----> dot |         | lot |    | dig |
    //             +--+--+         +--+--+    +--+--+
    //                |               |          |
    //             +--v--+         +--v--+       |
    //        +----> dog |         | log |       |
    //        |    +--+--+         +--+--+       |
    //        |       |               |          |
    //        |       |    +--v--+    |          |
    //        |       +--->| cog |<-- +          |
    //        |            +-----+               |
    //        |                                  |
    //        |                                  |
    //        +----------------------------------+
    
    class Solution {
    public:
        vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
            unordered_map<string, unordered_set<string>> parent = BFS(start, end, dict);
            
            vector<string> path; path.push_back(start);
            vector<vector<string>> paths;
            DFS(start, end, parent, path, paths);
            return paths;
        }
        
    private:
        unordered_map<string, unordered_set<string>> 
        BFS(const string &start, const string &end, const unordered_set<string> &dict) {
            
            /* 用于存储BFS形成的图结构 */
            unordered_map<string, unordered_set<string>> parent;
            
            /* 模拟图结构的每一层 */
            unordered_set<string> level[3];
            unordered_set<string> *previousLevel = &level[0];
            unordered_set<string> *currentLevel  = &level[1];
            unordered_set<string> *nextLevel     = &level[2];
            
            unordered_set<string> *p = NULL; // 用于交换指针用
            
            currentLevel->insert(start);
            
            /* BFS */
            
            bool flag = false;  // 当下一层插入的word中包含end,即退出BFS,因为所求为最短路径
            
            while (flag == false) {    // 还未到最后一层                              
                
                // 用于存储下一层的newWord(如果存在)
                nextLevel->clear();
                
                // 处理当前层
                for (const auto &word : *currentLevel) {             // 当前层中的每一个word
                    for (int ix = 0; ix < word.size(); ix++) {       // 当前单词的每一个letter
                        string newWord = word;                                            
                        for (char c = 'a'; c <= 'z'; c++) {          // 对当前letter依次进行26个字母的替换
                            
                            newWord[ix] = c;
                            
                            // 不在词典中或者之前层已经出现过
                            if (dict.count(newWord) == 0 || previousLevel->count(newWord) == 1 || currentLevel->count(newWord) == 1) {
                                continue;
                            }
                            
                            if (newWord == end) {
                                flag = true;
                                parent[word].insert(newWord);
                                continue;
                            }
                            
                            parent[word].insert(newWord);
                            nextLevel->insert(newWord);
                        }
                    }
                }
                
                if (nextLevel->empty()) {
                    break;
                }
                
                p = currentLevel;
                currentLevel = nextLevel;
                nextLevel = previousLevel;
                previousLevel = p;
            }
            
            if (flag == false) {
                parent.clear();
            }
            
            return parent;
        }
        
        
        void DFS(const string &start, const string &end, 
                 unordered_map<string, unordered_set<string>> &parent,
                 vector<string> &path,
                 vector<vector<string>> &paths) {
            if (parent.find(start) == parent.end()) {
                if (start == end) {
                    paths.push_back(path);
                }
                return;
            }
            
            for (const auto &word : parent[start]) {
                path.push_back(word);
                DFS(word, end, parent, path, paths);
                path.pop_back();
            }
        }
    };
  • 相关阅读:
    The 9th SWJTU ACM Final Tutorial
    The 9th SWJTU ACM Online Tutorial
    ACdream群赛(5) D Palindrome
    ACdream群赛(5)总结
    The 9th SWJTU ACM Qualification Tutorial
    IIUC Inter University Programming Contest 2012总结
    曾经流行的,即将流行的几种渲染模式(render pipeline)
    ogre线程及其死锁问题
    crysis shader系统简单分析
    编译并集成mono 2.6.4到应用程序中
  • 原文地址:https://www.cnblogs.com/jianxinzhou/p/4520613.html
Copyright © 2011-2022 走看看