• Word Ladder II


    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.

    思路:这道题很难,借鉴网上说法,基本思路是通过BFS从start到end,找的过程中记录前驱单词,在用DFS反向找回完整路径。要想恢复出单词变换的路径,就事先保存,保存的是该单词的前一变换单词,可能会出现很多个单词都能变换到当前单词,使用set来保存。用二维vector保存当前能够变换到的单词和变换出的这些单词的单词。每一维vector存放的都是以set类型。设存放当前可访问单词的vector下标为cur,存放变换出这些单词的vector下标为pre,那么每一轮开始更新cur之前,都要从字典里删除存放pre中存放的单词。同时清空cur中单词,然后从pre中变换到cur,使用map来记录变换到cur的单词。结束条件是在某一层变换之后发现了目标单词,那么就开始打印路径了。

    递归打印路径,主要是注意假设用引用做的话要合适的回退,且最后是反向打印的,应该把结果reverse下在放到结果集中去。

    class Solution {
    public:
        void getPath(vector<vector<string> > &result,unordered_map<string,vector<string> > &predict,vector<string> &pre,string &word)
        {
            //当这种情况出现时,也就是已经从end遍历到start,故可以做处理
            if(predict[word].size()==0)
            {
                pre.push_back(word);
                vector<string> tpre(pre);
                reverse(tpre.begin(),tpre.end());
                result.push_back(tpre);
                pre.pop_back();
                return;
            }
            pre.push_back(word);
            vector<string>::iterator iter;
            for(iter=predict[word].begin();iter!=predict[word].end();iter++)
            {
                getPath(result,predict,pre,*iter);
            }
            pre.pop_back();
        }
        vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
            vector<vector<string> > result;
            string word;
            unordered_map<string,vector<string> > predict;
            vector<string> pres;
            vector<unordered_set<string> > candidate(2);
            predict[start]=pres;
            int cur=0,pre=1,n=start.size();
            candidate[0].insert(start);
            while(true)
            {
                cur=!cur;
                pre=!pre;
                unordered_set<string>::iterator iter;
                for(iter=candidate[pre].begin();iter!=candidate[pre].end();iter++)
                {
                    dict.erase(*iter);
                }
                candidate[cur].clear();
                for(iter=candidate[pre].begin();iter!=candidate[pre].end();iter++)
                {
                    for(int i=0;i<n;i++)
                    {
                        word=*iter;
                        for(char ch='a';ch<='z';ch++)
                        {
                            if(word[i]==ch)
                                continue;
                            word[i]=ch;
                            if(dict.count(word)>0)
                            {
                                candidate[cur].insert(word);
                                predict[word].push_back(*iter);
                            }
                        }
                    }
                }
                if(candidate[cur].size()==0)
                    return result;
                if(candidate[cur].count(end))
                    break;
            }
            getPath(result,predict,pres,end);
            return result;
        }
    };
  • 相关阅读:
    运行一个内核模块
    ubuntu下解析udt数据包
    在脚本中使用export导出变量值
    安卓手机已保存WiFi密码查看助手(开源)
    hashmap先按照value从大到小排序,value相等时按照key从小到大排序
    python画柱状图并且输出到html文件
    匀速圆周运动向心加速度推导
    简单证明圆锥体积为三分之一圆柱
    排列组合的一些公式及推导(非常详细易懂)
    相同字符串问题_题解
  • 原文地址:https://www.cnblogs.com/awy-blog/p/3819930.html
Copyright © 2020-2023  润新知