[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();

        }

    }

};

你可能感兴趣的:(LeetCode)