zoukankan      html  css  js  c++  java
  • 【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;
        }
    };
  • 相关阅读:
    CodeForces 288A Polo the Penguin and Strings (水题)
    CodeForces 289B Polo the Penguin and Matrix (数学,中位数)
    CodeForces 289A Polo the Penguin and Segments (水题)
    CodeForces 540C Ice Cave (BFS)
    网站后台模板
    雅图CAD
    mbps
    WCF学习-协议绑定
    数据库建表经验总结
    资源位置
  • 原文地址:https://www.cnblogs.com/dplearning/p/4240364.html
Copyright © 2011-2022 走看看