lintcode:Word Ladder II

Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

Only one letter can be changed at a time
Each intermediate word must exist in the dictionary

参考:http://www.cnblogs.com/x1957/p/3526838.html

1.依然是BFS,记录每个的前驱节点father[x],当然这个father有多个;

采用分层遍历,只要到了end,那么这一层所有的都是最短的,一样长。

2.然后用DFS遍历father,从end到start

DFS递归完注意‘恢复现场’。

class Solution {
public:
    /**
    * @param start, a string
    * @param end, a string
    * @param dict, a set of string
    * @return a list of lists of string
    */

    void dfs(vector<vector<string>> &res,unordered_map<string,vector<string>> &father,
    vector<string> &path,string &start,string &end){

        path.push_back(end);
        if(end==start){
            vector<string> tmp(path);
            reverse(tmp.begin(),tmp.end());
            res.push_back(tmp);
            path.pop_back();
            return;
        }

        vector<string> fa=father[end];

        for(int i=0;i<fa.size();i++){
            string f=fa[i];
            dfs(res,father,path,start,f);
        }
        path.pop_back();
    }

    vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
        // write your code here
        vector<vector<string>> res;

        /*这里需要用set而不能用vector,会使得得到相同的最短路径*/
        unordered_set<string> current,next;

        unordered_set<string> visited;
        unordered_map<string,vector<string>> father;

        current.insert(start);

        bool found=false;

        while (!current.empty() && !found){

            for(string str:current){
                visited.insert(str);
            }

            for (string front:current){

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

                    for (int ch = 'a'; ch <= 'z'; ch++){

                        if(front[i]==ch) continue;

                        string tmp = front;
                        tmp[i] = ch;

                        if (tmp == end){
                            found=true;
                        }

                        if (dict.find(tmp)!=dict.end()  && visited.find(tmp)==visited.end() ){

                            father[tmp].push_back(front);

                            next.insert(tmp);
                        }
                    }
                }
            }

            current.clear();

            swap(current,next);

        }

        if(found){
            vector<string> path;
            dfs(res,father,path,start,end);
        }

        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值