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.
struct Node

{

    int vindex;

    int path;

    int previous;

};

class Solution {

public:

    vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) 

    {

        vector<vector<string>> result;

        int len=start.length();



        vector<string> vdict;

        map<string,int> ids;

        vdict.push_back(start);

        ids[start]=0;

        for(unordered_set<string>::iterator it=dict.begin();it!=dict.end();it++)

        {

            ids[*it]=vdict.size();

            vdict.push_back(*it);            

        }

        vdict.push_back(end);

        ids[end]=vdict.size()-1;



        dict.insert(start);

        dict.insert(end);



        vector<vector<int>>adj;

        for(int i=0;i<vdict.size();i++)

        {

            vector<int> adj0;

            string str=vdict[i];

            for(int j=0;j<len;j++)

            {

                for(char c='a';c<='z';c++)

                    if(vdict[i][j]!=c)

                    {

                        str[j]=c;

                        if(dict.count(str)) adj0.push_back(ids[str]);                        

                    }

                str[j]=vdict[i][j];

            }

            adj.push_back(adj0);

        }                                

        

        vector<Node*> path;        

        Node* newnode=new Node();

        newnode->vindex=ids[start];

        newnode->path=1;

        newnode->previous=-1;

        path.push_back(newnode);                                    



        int index=0;

        int minpath=0;        

        int oldpath=0;



        while(index<path.size())

        {            

            if(path[index]->path>oldpath)

            {

                oldpath=path[index]->path;

                int i=index;

                while(i<path.size())

                {                    

                    unordered_set<string>::iterator it= dict.find(vdict[path[i]->vindex]);

                    if(it!=dict.end()) dict.erase(it);

                    i++;

                }                

            }

            if(minpath>0 && path[index]->path==minpath)

                break;                

            // a path found

            if(path[index]->vindex==vdict.size()-1)

                minpath=path[index]->path;

            //next word

            for(int i=0;i<adj[path[index]->vindex].size();i++)

            {                   

                if(dict.count(vdict[adj[path[index]->vindex][i]]))

                {                            

                        newnode=new Node();

                        newnode->path=oldpath+1;

                        newnode->vindex=adj[path[index]->vindex][i];

                        newnode->previous=index;

                        path.push_back(newnode);

                }                        

            }

            index++;

        }



        for(int i=0;i<path.size();i++)

        if(path[i]->path==minpath && vdict[path[i]->vindex]==end)

        {

            vector<string> words;

            int index=i;

            do

            {

                words.insert(words.begin(),vdict[path[index]->vindex]);

                index=path[index]->previous;

            }

            while(index!=-1);

            result.push_back(words);

        }

        

        return result;

    }    

};

 

你可能感兴趣的:(word)