【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;

    }

};

 

你可能感兴趣的:(LeetCode)