您的位置:首页 > 其它

【广度优先遍历】leetcode - Word Ladder II

2015-05-13 18:00 357 查看
题目:leetcode

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

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.

class Solution {
public:
    vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
        vector<vector<string>> res;
        if(start==end && dict.count(start))
        {
            res.push_back(vector<string>(1,start));
            return res;
        }
        
        unordered_set<string> cur,next,used;
        unordered_map<string,unordered_set<string>> father;//键是单词,值是父亲,记录单词的父子关系
        cur.emplace(start);
        bool should_continue=true;
        
        while(should_continue && !cur.empty())
        {
            //mark临时记录父子关系
            //之所以设置mark记录本轮产生的父子关系,是因为同一个单词,可能有多个父亲,不能只记录一个,而且只能记录距离最近的父亲
            unordered_map<string,unordered_set<string>> mark;
            for(auto &i:next)
            {
                used.emplace(i);
            }
            //记得清空next!
            next.clear();
            for(auto word:cur)
            {
                set<string> r=NewWords(word,dict,used);
                for(auto i:r)
                {
                    if(i==end)
                        should_continue=false;
                    next.emplace(i);
                    if(father.count(i)==0)
                    {
                        mark[i].emplace(word);
                    }
                }
            }
            //把mark的内容导入father中
            for(auto &j:mark)
            {
                father[j.first]=j.second;
            }
            swap(cur,next);
        }
        //根据父子关系,重建路径
        find_path(father,start,end,res);
        return res;
    }
    
    
    void find_path(unordered_map<string, unordered_set<string>> &father, string start, string end, vector<vector<string>> &res)
	{
		vector<string> path;
		path.push_back(end);
		find_path_core(father, start, end, res, path);
	}

	void find_path_core(unordered_map<string, unordered_set<string>> &father, string start, string end, vector<vector<string>> &res, vector<string> &path)
	{
		if (end == start)
		{
			reverse(path.begin(), path.end());
			res.push_back(path);
			reverse(path.begin(), path.end());//注意!再反转回来!!!!
			return;
		}
		for (auto &i : father[end])
		{
		    if(find(path.begin(),path.end(),i)!=path.end())
		        continue;
			path.push_back(i);
			find_path_core(father, start, i, res, path);
			path.pop_back();
		}
	}
    
    set<string> NewWords(string &word,unordered_set<string> &dict,unordered_set<string> &used)
    {
         set<string> res;
        for(int i=0;i<word.size();++i)
        {
            char c=word[i];
            for(int j=0;j<26;++j)
            {
                char tmp='a'+j;
                if(tmp==c)
                    continue;
                word[i]=tmp;
                if(dict.count(word)>0 && used.count(word)==0)
                    res.emplace(word);
            }
             word[i]=c;//注意还原单词
        }
        return res;
    }
    
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: