Leetcode: Word Ladder II

Question

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.

Thoughts

1. preprocess the dictionary and build a graph. Adjacent nodes' distance is 1

2. using BFS iterator the graph

3. array father can record the father-son relation in iteration effectively

4. source code contains unordered_set, so when compiled under Linux system, extra flag must be used. 

-std=c++11 or

-std=c++0x

 

code Runtime error. Can't figure out why...

#include <iostream>

#include <string>

#include <deque>

#include <vector>

#include <unordered_set>

#include <unordered_map>

#include <algorithm>

using namespace std;



class Solution {

public:

    vector<string> dct;

    vector<int>  graph[10010];

    int father[10010];

    int minDepth;

    vector<vector<string> > res;

    vector<string> party;



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

        res.clear(), party.clear();

        dct.clear();

        for(int i = 0; i < dict.size()+3; i ++) {

            graph[i].clear();

            father[i] = -3;

            minDepth = -1;

        }



        if(dist(start, end) == 1) {

            party.push_back(start), party.push_back(end);

            res.push_back(party);

            return res;

        }



        preprocess(dict);

        deque<int> queue;

        queue.clear();

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

            if(dist(start, dct[i]) == 1) {

                queue.push_back(i);

                father[i] = -1;

                //cout << i << endl;

            }

        }



        while(!queue.empty()) {

            int nextInt = queue.front();

            queue.pop_front();



            if(dist(end, dct[nextInt]) == 1) { // µÖ´ïÖÕµã, ´æ´¢Í˳ö

                // handler otherwise

                minDepth = assemble(party, nextInt, start, end);

                res.push_back(party);

                party.clear();

                while(!queue.empty()) {

                    int finalInt = queue.front();

                    queue.pop_front();

                    if(dist(end, dct[nextInt]) == 1) {

                        if(assemble(party, finalInt, start, end) == minDepth) {

                            res.push_back(party);

                            party.clear();

                        }else{

                            return res;

                        }

                    }

                }

                return res;

            }



            for(int j = 0; j < graph[nextInt].size(); j ++) {

                int candidate = graph[nextInt][j];

                if(father[candidate] == -3) {

                    father[candidate] = nextInt;

                    queue.push_back(candidate);

                }

            }

        }

    }



    int dist(const string &in, const string &ths) {

        int dis = 0;

        for(int i = 0; i < in.size() && dis < 2; i++) {

            if(in[i] != ths[i])

                dis ++;

        }

        return dis;

    }



    void preprocess(unordered_set<string> &dict) {

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

            dct.push_back(*it1);

        

        // ¹¹½¨ÁÚ½Ó±í

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

            for(int j = 0; j < dct.size(); j ++) {

                if(dist(dct[i], dct[j]) == 1) {

                    graph[i].push_back(j);

                }

            }

        }

    }



    int assemble(vector<string> &party, const int &nextInt, const string &start, const string &end) {

        party.push_back(end);

        int pre = nextInt;

        while(pre != -1 && pre >= 0) { //WA?

            party.push_back(dct[pre]);

            pre = father[pre];

        }   

        party.push_back(start);

        reverse(party.begin(), party.end());

        return party.size();

    }

};



int main() {

    string start = "hot";

    string end = "dog";

    unordered_set<string> dict;

    dict.insert("hot");

    dict.insert("dog");

    dict.insert("dot");

    //dict.insert("lot");

    //dict.insert("log");

    

    Solution solution;

    vector<vector<string> > res = solution.findLadders(start, end, dict);



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

        for(int j = 0; j < res[i].size(); j ++) {

            cout << res[i][j] << " ";

        }

        cout << endl;

    }

    return 0;

}

  

你可能感兴趣的:(LeetCode)