• leetcode——Word Ladder II


        改了3个晚上终于没有bug了。。。结果超时了。。。我已经想不出该怎么优化了。。。。看了答案,是一层一层遍历,然后将每个单词的父节点push进一个vector里,我也是一层层,并且如果在下一层遇到上一层的某个单词,就记录单词被访问过,就不会再访问了。。。就是想不明白为啥用的时间要多很多。。。难道是因为我的代码不够简洁么?!!。。。

    class Solution {
        // 用广度搜索,建立由start开始的搜索树,子节点为父节点只改变一个字母在字典里能查到的所有的单词
        // 每个子节点能记录其父节点及其所在最小层数,保证最短路径
        // 建立完树之后,遍历树,若结点能转换为end,则将其到start的路径记录,并加入sequences
    private:
        vector<vector<string> > sequences; // 记录结果
    public:
        vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
            unordered_map<string, pair<queue<string>, int> > father; // 记录父节点及层数
            unordered_set<string> visited; // 记录已访问过
            vector<string> sequence;
            queue<string> que;
            int shortest(INT_MAX); // 到end最短的序列
            if (start.size() != end.size() || start.size() < 1) return sequences;
            int size = start.size();
            if (size == 1) {
                sequence.push_back(start);
                sequence.push_back(end);
                sequences.push_back(sequence);
                return sequences;
            }
            // 访问根节点入队,记录父节点极其层数
            que.push(start); 
            queue<string> fq; fq.push("");
            father[start] = make_pair(fq, 1);
            while (!que.empty()){
                // 出队
                string word = que.front();
                que.pop();
                // 改变字母
                for (int i = 0; i < size; i++){
                    for (char c = 'a'; c <= 'z'; c++){
                        if (c == word[i]) continue;
                        string newWord = word;
                        newWord    = newWord.replace(i, 1, 1, c);
                        // 如果是end,则若是第一次出现则是最短路径
                        // 因为是一层一层地搜索,所以第一次搜索到end则是最短的
                        // 若是最短路径,则记录路径,加入sequences
                        if (newWord == end) {
                            if (shortest == INT_MAX) shortest = father[word].second + 1;
                            int curLayer = father[word].second + 1;
                            if (curLayer = shortest) addSequence(father, start, end, word);
                        }
                        // 如果在字典里且没访问过
                        if (dict.find(newWord) != dict.end() && visited.find(newWord) == visited.end())
                        {
                            // 入队,记录其所在层及其父节点
                            int layer = father[word].second;
                            // 若newWord没有父节点,则创建
                            if (father.find(newWord) == father.end()){
                                que.push(newWord);
                                queue<string> fq;
                                fq.push(word);
                                father[newWord] = make_pair(fq, layer + 1);
                            }//若newWord已有父节点,且newWord的层数比现在word的层数多1,则增加其父节点
                            else    if (layer <= (father[newWord].second - 1)){
                                que.push(newWord);
                                auto fq = father[newWord].first;
                                fq.push(word);
                                father[newWord] = make_pair(fq,layer + 1);
                            }// 若newWord有父节点,且当前层数大于其最小层数,则标记其为访问过
                            else{
                                visited.insert(newWord);
                            }
                            
                        }
                    }
                }
            }
            return sequences;
        }
        inline void addSequence(unordered_map<string, pair<queue<string>, int> > &father, string start, string end, string word){
            vector<string> sequence;
            if(word != end) sequence.push_back(word);
            sequence.push_back(end);
            auto wordfather = father[word].first;
            auto fatherWord = wordfather.front();
            auto n = father[word].second;
            if (wordfather.size() > 1) {
                wordfather.pop();
                father[word] = make_pair(wordfather, n);
            }
            word = fatherWord;
            while (word != start && word != ""){
                sequence.insert(sequence.begin(), word);
                wordfather = father[word].first;
                auto fatherWord = wordfather.front();
                auto n = father[word].second;
                if (wordfather.size() > 1) {
                    wordfather.pop();
                    father[word] = make_pair(wordfather, n);
                }
                word = fatherWord;
            }
            if (sequence[0] != start) sequence.insert(sequence.begin(), start);
            sequences.push_back(sequence);
        }
    };
  • 相关阅读:
    关于celery django djangocelery搭配报错问题及解决方法
    django 1048错误原因及解决思路
    CSS ::Selection
    Win7编程:在按钮中加入管理员权限运行盾牌图标转载
    VisualStudioVS2010统计代码行数
    在套用母版页的页面中应用input file上传图片
    Asp.Net Url 传值出现乱码的解决方法(包括js传值)
    JS验证码刷新无反应原因
    AspnetPager
    fckeditor2.6在IE9下的弹出窗口报错问题解决
  • 原文地址:https://www.cnblogs.com/skysand/p/4192343.html
Copyright © 2020-2023  润新知