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.

分析:BFS+DFS

 用两个unordered_set<string> cur和pre代替queue,cur表示当前层,prev表示上一层。大体思路上超时版本相同,先用bfs产生一个从start到end的最小路径图(通过记录节点前驱)。再用dfs生成从start到end的所有路径。代码如下:

class Solution {
public:
    unordered_map<string, vector<string>> father;
    
    vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
        vector<vector<string> > result;
        if(start == end)
            return vector<vector<string> >(1, vector<string>(2, start));
        
        unordered_set<string> used;
        unordered_set<string> prev;
        bool found = false;
        
        prev.insert(start);
        
        while(!prev.empty() && !found){
            unordered_set<string> cur;
            for(auto i = prev.begin(); i != prev.end(); i++){
                used.insert(*i);
                string tmp = *i;
                for(int j = 0; j < tmp.length(); j++)
                    for(char c = 'a'; c <= 'z'; c++)
                        if(tmp[j] != c){
                            swap(tmp[j], c);
                            if(dict.find(tmp) != dict.end() && used.find(tmp) == used.end() && prev.find(tmp) == prev.end()){
                                cur.insert(tmp);
                                father[tmp].push_back(*i);
                                if(tmp == end) found = true;
                            }
                            swap(tmp[j], c);
                        }
            }
            prev = cur;
        }
        
        if(found){
            vector<string> path;
            generate_path(result, path, start, end);
        }
        
        return result;
    }
    
    void generate_path(vector<vector<string> > &result, vector<string> &path, string start, string s){
        path.push_back(s);
        if(s == start){
            result.push_back(path);
            reverse(result.back().begin(), result.back().end());
        }else{
            for(auto i = father[s].begin(); i != father[s].end(); i++)
                generate_path(result, path, start, *i);
        }
        path.pop_back();
    }
};

 

posted on 2014-10-29 17:45  Ryan-Xing  阅读(190)  评论(0编辑  收藏  举报