zoukankan      html  css  js  c++  java
  • [LeetCode] Word Ladder II(bfs、dfs)

    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"]
      ]
    
    以下思路(Leetcode的discuss中,代码也是,以后自己重新写):
     solution:  
    1) first use bfs to create the graph(即unordered_multimap<string, string> path_map,每个元素由2个string组成,
    key表示路径中的当前字符串,value表示当前字符串的前一个字符串
    ),
    and by using data structure like unorderedmultimap and unorderedset,
    I can enhance the speed, one important thing is to change letter to get the interval word,
    not by comparing each word in the dict.   
    2) after getting the graph, use dfs to find all the paths from start to end.(主要理解path_map.equal_range(curr);map的成员函数equal_range,
    使用此函数得到一个字符串的多个前驱字符串,然后每个前驱字符串进行dfs,即深度优先搜索(这里用的递归)得到path值)
    class Solution {
    public:
        unordered_multimap<string, string> path_map;
        vector<vector<string> > res;
        unordered_set<string> visited;
    
        vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
            dict.insert(start);
            dict.insert(end);
            dict.erase(start);
            path_map.clear();
    
            unordered_set<string> last_layer, curr_layer;
            curr_layer.insert(start);
    
            while (!last_layer.empty() || !curr_layer.empty())
            {//得到path_map,每个元素由2个string组成,key表示路径中的当前字符串,value表示当前字符串的前一个字符串
    
    
                for (unordered_set<string>::iterator cit = last_layer.begin(); cit != last_layer.end(); ++cit)
                {
                    dict.erase(*cit);
                }
                last_layer.clear();
    
                for (unordered_set<string>::iterator cit = curr_layer.begin(); cit != curr_layer.end(); ++cit)
                { //找到上一层所有字符串的相邻字符串
                    string cur = *cit;
    
                    for (int i = 0; i < cur.size(); ++i)
                    {
                        string handle_str = cur;
                        int stop = handle_str[i] - 'a';
    
                        for (int j = (stop+1)%26; j != stop; j = (j+1)%26)
                        {
                            handle_str[i] = 'a' + j;
    
                            if (dict.find(handle_str) != dict.end())
                            {
                                last_layer.insert(handle_str);
                                path_map.insert(pair<string, string>(handle_str, cur));
                            }
                        }
                    }
                }
    
                if (last_layer.count(end))
                    break;
                curr_layer = last_layer;
            }
    
            vector<string> path;
    
            if (!path_map.empty())
                get_path(end, start, path);
            return res;
        }
    
        void get_path(string curr, string start, vector<string> path)
        {////在path_map中从end开始开始查到start
            if (curr == start)
            {
                path.insert(path.begin(), start);
                res.push_back(path);
                //path.clear();
                return;
            }
    
            unordered_multimap<string, string>::iterator it;
    
            pair<unordered_multimap<string, string>::iterator, unordered_multimap<string, string>::iterator> itrangexx = path_map.equal_range(curr);
            it = itrangexx.first;
            while (true)
            {            
                path.insert(path.begin(), curr);//在path.begin()前面插入值为curr的元素
    
                if (it != path_map.end() && it != itrangexx.second && visited.find(it->second) != visited.end())
                {    
                    ++it;
    
                }
    
                if (it == itrangexx.second || it == path_map.end())
                    break;
                else
                {
                    string prev;
    
                    prev = it->second;
                    visited.insert(prev);
    
                    get_path(prev, start, path);
    
                    visited.erase(prev);
                    if (!path.empty())
                        path.erase(path.begin());
                }
                ++it;
            }
        }
    };
  • 相关阅读:
    FCKeditor 2.3 在ASP.NET中的设置和使用
    如何去掉重复记录的Sql语句写法
    asp.net如何去掉HTML标记
    Asp.net中如何删除cookie?
    怎样得到select所有option里的值
    HttpModule是如何工作的
    Asp.net2.0下的表单验证Cookieless属性
    FreeTextBox实现机制
    ajax实现动态从数据库模糊查询显示到下拉框中(ajax方法返回Dataset的例子)
    新浪博客自动发表程序,请勿用于非法用途
  • 原文地址:https://www.cnblogs.com/Xylophone/p/3885363.html
Copyright © 2011-2022 走看看