[LeetCode]—Word LadderII 单词递推II

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"]
  ]
       在wordLadder 基础上,需要记录路径,记录前驱节点,最后使用深搜来查找路径。要保证路径最短,那么要注意同层之间不能互指,访问过的结点不能再访问。

    

学习自:https://gitcafe.com/soulmachine/LeetCode


class Solution {
public:
    vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) {
           unordered_set<string> visited; //判重
           unordered_set<string> current,next; //当前层和下一层,用集合是为了去重
           unordered_map<string,vector<string> > father;

           int level=0;  //层数
           bool found=false;

           current.insert(start);
           while(!current.empty() && !found){
                ++level;
                //将本层全部置为已访问,防止同层之间互指,导致路径非最短
                for(auto word : current)
                    visited.insert(word);
                for(auto word : current){
                    for(size_t i=0;i<word.size();++i){
                        string new_word=word;
                        for(char c='a';c<='z';c++){
                            if(c==new_word[i])continue;
                            swap(c,new_word[i]);

                            if(new_word==end)found=true; //找到了

                            if(visited.count(new_word)==0
                                    && (dict.count(new_word)>0 || new_word==end)){
                                next.insert(new_word);
                                father[new_word].push_back(word);
                            }
                            swap(c,new_word[i]);
                        }

                    }
                }
                current.clear();
                swap(current,next);
           }
            vector<vector<string> > result;
            if(found){
                vector<string> path;
                buildPath(father,path,start,end,result);
            }
            return result;
    }
private:
    void buildPath(unordered_map<string,vector<string> > &father,
            vector<string> &path,const string &start,const string &word,
            vector<vector<string> > &result){
        path.push_back(word);
        if(start==word){
         result.push_back(path);
         reverse(result.back().begin(),result.back().end());
        }else{
            for (auto f : father[word])
                buildPath(father,path,start,f,result);
        }
        path.pop_back();
    }
};



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值