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

  

posted @ 2014-01-12 09:52  SangS  阅读(652)  评论(0编辑  收藏  举报