• 【leetcode】Word Ladder II(hard)★ 图 回头看


    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"]
      ]

    思路:

    我自己用回溯做,结果超时了。代码和注释如下: 很长

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #include <unordered_set>
    #include <string>
    using namespace std;
    
    class Solution {
    public:
        vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
            vector<vector<string>> ans;
            vector<string> hash; //记录单词是否已经生成
            vector<string> X;
            vector<vector<string>> S;
            vector<int> hashlength; //记录在k = 0 - ... 时 hash 的长度 方便弹出
    
            int minlen = 1000;
            int k = 0;
            hash.push_back(start);
            hashlength.push_back(1);
            if(S.size() <= k)
            {
                S.push_back(vector<string>());
            }
            S[k].push_back(start);
    
            while(k >= 0)
            {
                while(!S[k].empty())
                {
                    X.push_back(S[k].back());
                    S[k].pop_back();
    
                    if(onedifferent(X.back(), end))
                    {
                        X.push_back(end);
                        if(k == minlen) //只存长度最短的
                        {
                            ans.push_back(X);
                        }
                        if(k < minlen) //如果有新的最短长度 ans清空,压入新的最短答案
                        {
                            minlen = k;
                            ans.clear();
                            ans.push_back(X);
                        }
                    }
                    else if(k < minlen) //k如果>= minlen 那么后面的结果肯定大于最短长度
                    {
                        k++;
                        if(S.size() <= k) //如果S的长度不够 扩大S长度
                        {
                            S.push_back(vector<string>());
                        }
                        if(hashlength.size() <= k)//如果hashlength的长度不够 扩大其长度
                        {
                            hashlength.push_back(0);
                        }
                        unordered_set<string>::iterator it;
                        for(it = dict.begin(); it != dict.end(); it++) //对字典中的数字遍历,得到下一个长度可以用的备选项
                        {
                            if(onedifferent(X.back(), *it) && (find(hash.begin(), hash.end(), *it) == hash.end()))
                            {
                                hashlength[k]++;
                                hash.push_back(*it);
                                S[k].push_back(*it);
                            }
                        }
                    }
                }
                k--;
                while(k >= 0 && hashlength[k]) //把当前层压入hash的值都弹出
                {
                    hash.pop_back();
                    hashlength[k]--;
                }
                while(k >= 0 && X.size() > k) //把当前层压入X的值弹出
                {
                    X.pop_back();
                }
            }
    
            return ans;
        }
    
        bool onedifferent(string s1, string s2) //判断s1是否可以只交换一次得到s2
        {
            int diff = 0;
            for(int i = 0; i < s1.size(); i++)
            {
                if(s1[i] != s2[i])
                    diff++;
            }
            return (diff == 1);
        } 
    };
    
    int main()
    {
        Solution s;
        unordered_set<string> dict;
        dict.insert("hot");
        dict.insert("dot");
        dict.insert("dog");
        dict.insert("lot");
        dict.insert("log");
    
        string start = "hit";
        string end = "cog";
    
        vector<vector<string>> ans = s.findLadders(start, end, dict);
    
        return 0;
    }

    别人的思路:我没怎么看,只知道是用图的思想 速度也不快 差不多1000ms的样子

    class Solution {
    public:
        vector<vector<string>> helper(unordered_map<string,vector<string>> &pre,string s,unordered_map<string,int>&visit,string start){
            vector<vector<string> > ret,ret1;vector<string> t_ret;
            if(s==start) {t_ret.push_back(s);ret.push_back(t_ret);return ret;}
            for ( auto it = pre[s].begin(); it != pre[s].end(); ++it ){
                ret1=helper(pre,*it,visit,start);
                for(int i=0;i<ret1.size();i++){
                    ret1[i].push_back(s);
                    ret.push_back(ret1[i]);
                } ret1.clear();
            }
            return ret;
        }
        vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
            unordered_map<string,vector<string> > graph;unordered_map<string,int> visit;unordered_map<string,vector<string>> pre;
            vector<vector<string> > ret; vector<string> t_ret;
            if(start==end){t_ret.push_back(start);t_ret.push_back(end);ret.push_back(t_ret);return ret;}
            dict.insert(start);dict.insert(end);
            for ( auto it = dict.begin(); it != dict.end(); ++it ){
                string t=*it; visit[t]=0;
                for(int i=0;i<t.size();i++)
                    for(int j='a';j<='z';j++){
                        if(char(j)==t[i]) continue;
                        string tt=t;
                        tt[i]=char(j);
                        if(dict.count(tt)>0) graph[t].push_back(tt);
                    }
            }
            queue <string> myq;
            myq.push(start);
            while(!myq.empty()){
                for(int i=0;i<graph[myq.front()].size();i++){
                    if( visit[graph[myq.front()][i]]==0){
                        visit[graph[myq.front()][i]]=visit[myq.front()]+1;
                        myq.push(graph[myq.front()][i]);
                        pre[graph[myq.front()][i]].push_back(myq.front());
                    }
                    else if(visit[graph[myq.front()][i]]>0&&visit[graph[myq.front()][i]]>=visit[myq.front()]+1){
                        if(visit[graph[myq.front()][i]]>visit[myq.front()]+1){
                            visit[graph[myq.front()][i]]=visit[myq.front()]+1;
                             pre[graph[myq.front()][i]].push_back(myq.front());
                        }else  pre[graph[myq.front()][i]].push_back(myq.front());;
                    }
                }
                visit[start]=1;
                myq.pop();
            }
            if(visit[end]==0) return ret; 
            ret=helper(pre,end,visit,start);
            return ret;
        }
    };
  • 相关阅读:
    使用Visual Studio给SharePoint列表添加Event Receiver
    使用客户端对象模型回写SharePoint列表
    思考:通过源码进行安装的前提是什么
    思考:学习一门语言真的是仅仅只有为了使用吗?或者说学习一个语言如果在工作中不使用,那么学习它还有什么好处和价值呢?
    思考:(使用下载工具比如yum,maven等)下载(库或者jar)到本地都需要设置源
    思考:代码块的大小是进行代码抽出一个方法或者进行重构或者是否在设计时设计为一个方法的衡量因素之一吗?
    思考:对源的包装是为了更好的隔离和在中间插入一些层?
    Spring Cloud和Spring Boot的认识
    如何对待基础知识:
    为什么总觉得事情应付不过来,总觉得事情需要花费很多时间?
  • 原文地址:https://www.cnblogs.com/dplearning/p/4240364.html
Copyright © 2020-2023  润新知