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;
            }
        }
    };
  • 相关阅读:
    【SQL触发器】类型 FOR 、AFTER、 Instead of到底是什么鬼
    Oracle两种临时表的创建与使用详解
    oracle 临时表(事务级、会话级)
    oracle存储过程游标的使用(批号分摊)
    delphi FastReport快速入门
    Vue 表情包输入组件的实现代码
    一个基于 JavaScript 的开源可视化图表库
    浅淡Webservice、WSDL三种服务访问的方式(附案例)
    记录一下遇到的问题 java将json数据解析为sql语句
    Oracle词汇表(事务表(transaction table)”)
  • 原文地址:https://www.cnblogs.com/Xylophone/p/3885363.html
Copyright © 2011-2022 走看看