【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;
    }
};
原文地址:https://www.cnblogs.com/dplearning/p/4240364.html