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;
            }
        }
    };
  • 相关阅读:
    android 运行时异常捕获
    汇编32位寄存器和地址编号的五种书写形式
    各种进制的乘法表,八进制的加法,和数字的源码你,反码,和补码
    第一个c程序和vs2017 在打开MFC rc文件时找不到rcdll.dl
    asdfasdf
    php如何判断一个字符串是否包含另一个字符串
    php计算时间差/两个时间日期相隔的天数,时,分,秒.
    PHP服务器时间差8小时解决方案
    历年学生作品评论
    第一周例行报告
  • 原文地址:https://www.cnblogs.com/Xylophone/p/3885363.html
Copyright © 2011-2022 走看看