zoukankan      html  css  js  c++  java
  • leetcode-Word Ladder II

    Word Ladder II

     Total Accepted: 6164 Total Submissions: 58601My Submissions

    Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

    1. Only one letter can be changed at a time
    2. 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.

    此题是word Ladder的扩展,要找出全部的最短变换序列。要注意的问题是在扩展当前字符串时,假设找到了一个在字典中出现的字符串,不能马上删除该字符串,由于可能当前扩展的字符串所在层中其它字符串也可能变换到同一个字符串,所以我用了一个容器来保存当前层节点能扩展到的字符串,当前层遍历完时才从字典中删除这些字符串。

    尝试过用queue来保存当前队列,用vector来保存那些扩展到的字符串,可惜TLE。
    class Solution {
    public:
        vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
            if (start == end) {
                vector<string> v = {start};
                ret.push_back(v);
                return ret;
            }
            if (dict.empty())
                return ret;
            //Use vector to implement bfs operation
            queue<string> q;
            unordered_map<string, vector<string>> preStrMap;
            q.push(start);
            dict.erase(start);
            
            int currLevelLens = 1, nextLevelLens, head(0);
            string headStr, str;
            bool found = false;
            
            while (currLevelLens) {
                nextLevelLens = 0;
                vector<string> levelStrs;
                while (currLevelLens--) {  // Traverse the node of current level
                    headStr = q.front();
                    q.pop();
    
                    for (int i=0; i<headStr.size(); ++i) {
                        for (char j='a'; j<='z'; ++j) { // transform
                            if (headStr[i]==j)
                                continue;
                            str = headStr;
                            str[i] = j;
                            
                            if (str == end) { // record the previous string
                                found = true;
                                preStrMap[end].push_back(headStr);
                                continue;
                            }
                            
                            if (dict.find(str) != dict.end()) { 
                                ++nextLevelLens;
                                q.push(str);
                                levelStrs.push_back(str); // record the string of next level
                                preStrMap[str].push_back(headStr); // record the previous string
                            }
                        }
                    }
                }
                if (found)
                    break;
                for (int i=0; i<levelStrs.size(); ++i)
                    dict.erase(levelStrs[i]);
                
                currLevelLens = nextLevelLens;
                if (!currLevelLens) 
                    return ret;
            }
            vector<string> paths;
            genPaths(paths, preStrMap, end);
            return ret;
        }
    private:
        void genPaths(vector<string>& paths, unordered_map<string,vector<string>> &preStrMap, string& curr) {
            paths.push_back(curr);
            if (preStrMap[curr].empty())
                ret.push_back(vector<string>(paths.rbegin(), paths.rend()));
            for (auto itr = preStrMap[curr].begin(); itr != preStrMap[curr].end(); ++itr) {
                genPaths(paths, preStrMap, *itr);
            }
            paths.pop_back();
                
        }
        vector<vector<string>> ret;
    };

    然后用了两个unordered_set容器来保存,轻松通过。
    class Solution {
    public:
        vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
            if (dict.empty())
                return ret;
            //Use unordered_set to implement bfs operation
            unordered_set<string> q1, q2;
            unordered_map<string, vector<string>> preStrMap;
            q1.insert(start);
            dict.erase(start);
    
            while (true) {
                for (USS_CITR itr=q1.begin(); itr!=q1.end(); ++itr) {
                    string str = *itr;
                    for (int i=0; i<str.size(); ++i) {
                        for (int j='a'; j<='z'; ++j) {
                            if (str[i] == j) {
                                continue;
                            }
                            char c = str[i];
                            str[i] = j;
                            if (dict.find(str) != dict.end() || str==end) {
                                q2.insert(str);
                                preStrMap[str].push_back(*itr);
                            }
                            str[i] = c;
                        }
                    }
                }
                if (q2.find(end) != q2.end()) {
                    break;
                }
                for (USS_CITR itr=q2.begin(); itr!=q2.end(); ++itr) {
                    dict.erase(*itr);
                }
                q1.clear();
                q1.swap(q2);
                if (q1.empty()) {
                    return ret;
                }
            }
            vector<string> paths;
            genPaths(paths, preStrMap, end);
            return ret;
        }
    private:
        typedef unordered_set<string>::const_iterator USS_CITR;
        void genPaths(vector<string>& paths, unordered_map<string,vector<string>> &preStrMap, string& curr) {
            paths.push_back(curr);
            if (preStrMap[curr].empty())
                ret.push_back(vector<string>(paths.rbegin(), paths.rend()));
            for (auto itr = preStrMap[curr].begin(); itr != preStrMap[curr].end(); ++itr) {
                genPaths(paths, preStrMap, *itr);
            }
            paths.pop_back();
                
        }
        vector<vector<string>> ret;
    };





  • 相关阅读:
    php二维数组排序
    重学C语言 -- printf,scanf
    php调试利器 -- xdebug
    composer php依赖管理工具
    现代php开发
    php新特性--持续更新
    2016年书单
    jenkins集成gitlab实现自动合并
    etcd安装
    nginx 日志切割
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4067151.html
Copyright © 2011-2022 走看看