题目:

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.
  • 解题思路:

  • 这道题可真是耗费我老多时间,提交结果要不就是超时,要不就是内存限制,哎,编程能力急待提高啊。
  • 本题是Word Ladder的升级版,可对我这菜鸟才说升的可不止一级。该题主要的解题思路就是BFS+DFS。首先如Word Ladder,构造抽象图,然后利用BFS找到从start到end的最短路径,但寻找最短路径的过程中,我们需要保持最短路径最个节点的父节点信息,以便之后进行所有最短路径结果的重构,重构路径采用的DFS回溯,从end节点开始一直到start节点。好了,不多说了,直接上代码。
  • 实现代码:(注:该代码未能AC,出现内存限制,忘牛人指正,实在不知错在哪里)
  • #include <iostream>
    #include <string>
    #include <vector>
    #include <queue>
    #include <unordered_set>
    #include <unordered_map>
    #include <algorithm>
    using namespace std; /**
    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>> resvec;
    if(start.empty() || end.empty() || dict.empty())
    return resvec;
    unordered_map<string, vector<string>> premap;
    //这里需要用到两个vector来模拟两个队列而不是直接用两个队列,是因为需要对队列进行遍历,queue做不到
    vector<string> squ[2];
    squ[0].push_back(start);
    bool qid = false;
    bool finish = false;
    while(!squ[qid].empty())
    {
    squ[!qid].clear();
    vector<string>::iterator iter;
    for(iter = squ[qid].begin(); iter != squ[qid].end(); ++iter)
    dict.erase(*iter);//从dict中删除同一层的所有节点,以免造成循环操作
    for(iter = squ[qid].begin(); iter != squ[qid].end(); ++iter)//处理同一层节点
    {
    string curstr = *iter;
    for(int i = 0; i < curstr.size(); i++)
    {
    char t = curstr[i];
    for(char j = 'a'; j <= 'z'; j++)
    {
    if(j == curstr[i])
    continue;
    curstr[i] = j;
    if(curstr == end)
    {
    finish = true;
    premap[curstr].push_back(*iter); }
    else if(dict.count(curstr) > 0)
    {
    squ[!qid].push_back(curstr);
    premap[curstr].push_back(*iter);
    }
    }
    curstr[i] = t; }
    }
    if(finish)//说明已经处理到了end节点,可以直接break循环,进行结果重构了
    break;
    qid = !qid;//表示将要处理的下一层
    }
    if(premap.count(end) == 0)//表明end节点的父节点不存在,所有没有到end的转换,直接返回空resvec
    return resvec;
    vector<string> tmp;
    getResult(resvec, tmp, premap, start, end);
    return resvec;
    } //DFS
    void getResult(vector<vector<string> > &resvec, vector<string> &tmp,
    unordered_map<string, vector<string> > &premap, string &start, string &cur)
    {
    tmp.push_back(cur);
    if (cur == start)
    {
    resvec.push_back(tmp);
    reverse(resvec.back().begin(), resvec.back().end());
    }
    else
    {
    vector<string> v = premap[cur];
    for (int i = 0; i < v.size(); i++)
    {
    getResult(resvec, tmp, premap, start, v[i]);
    }
    }
    tmp.pop_back();
    }
    }; int main(void)
    {
    string start("hit");
    string end("cog");
    string strarr[] = {"hot","dot","dog","lot","log"};
    int n = sizeof(strarr) / sizeof(strarr[0]);
    unordered_set<string> dict(strarr, strarr+n);
    Solution solution;
    vector<vector<string>> resvec = solution.findLadders(start, end, dict);
    vector<vector<string>>::iterator iter;
    for(iter = resvec.begin(); iter != resvec.end(); ++iter)
    {
    vector<string> tmp = *iter;
    vector<string>::iterator it;
    for(it = tmp.begin(); it != tmp.end(); ++it)
    cout<<*it<<" ";
    cout<<endl;
    }
    return 0;
    }

    以下附网上大神AC代码一份:

    class Solution {
    public:
    vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict)
    {
    result_.clear();
    unordered_map<string, vector<string>> prevMap;
    for(auto iter = dict.begin(); iter != dict.end(); ++iter)
    prevMap[*iter] = vector<string>();
    vector<unordered_set<string>> candidates(2);
    int current = 0;
    int previous = 1;
    candidates[current].insert(start);
    while(true)
    {
    current = !current;
    previous = !previous;
    for (auto iter = candidates[previous].begin(); iter != candidates[previous].end(); ++iter)
    dict.erase(*iter);
    candidates[current].clear(); for(auto iter = candidates[previous].begin(); iter != candidates[previous].end(); ++iter)
    {
    for(size_t pos = 0; pos < iter->size(); ++pos)
    {
    string word = *iter;
    for(int i = 'a'; i <= 'z'; ++i)
    {
    if(word[pos] == i)continue;
    word[pos] = i;
    if(dict.count(word) > 0)
    {
    prevMap[word].push_back(*iter);
    candidates[current].insert(word);
    }
    }
    }
    }
    if (candidates[current].size() == 0)
    return result_;
    if (candidates[current].count(end)) break;
    }
    vector<string> path;
    GeneratePath(prevMap, path, end);
    return result_;
    } private:
    void GeneratePath(unordered_map<string, vector<string>> &prevMap, vector<string>& path, const string& word)
    {
    if (prevMap[word].size() == 0)
    {
    path.push_back(word);
    vector<string> curPath = path;
    reverse(curPath.begin(), curPath.end());
    result_.push_back(curPath);
    path.pop_back();
    return;
    }
    path.push_back(word);
    for (auto iter = prevMap[word].begin(); iter != prevMap[word].end(); ++iter)
    GeneratePath(prevMap, path, *iter);
    path.pop_back();
    }
    vector<vector<string>> result_;
    };

    代码来源:http://blog.csdn.net/doc_sgl/article/details/13341405

    LeetCode127:Word Ladder II的更多相关文章

    1. 18. Word Ladder && Word Ladder II

      Word Ladder Given two words (start and end), and a dictionary, find the length of shortest transform ...

    2. [leetcode]Word Ladder II @ Python

      [leetcode]Word Ladder II @ Python 原题地址:http://oj.leetcode.com/problems/word-ladder-ii/ 参考文献:http://b ...

    3. LeetCode: Word Ladder II 解题报告

      Word Ladder II Given two words (start and end), and a dictionary, find all shortest transformation s ...

    4. [Leetcode Week5]Word Ladder II

      Word Ladder II 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/word-ladder-ii/description/ Descripti ...

    5. 126. Word Ladder II(hard)

      126. Word Ladder II 题目 Given two words (beginWord and endWord), and a dictionary's word list, find a ...

    6. [LeetCode] Word Ladder II 词语阶梯之二

      Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from ...

    7. 【leetcode】Word Ladder II

        Word Ladder II Given two words (start and end), and a dictionary, find all shortest transformation ...

    8. LeetCode :Word Ladder II My Solution

      Word Ladder II Total Accepted: 11755 Total Submissions: 102776My Submissions Given two words (start  ...

    9. [LeetCode] 126. Word Ladder II 词语阶梯之二

      Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...

    随机推荐

    1. 【网络编程】——connect函数遇见EINTR的处理

      最近在公司项目中突然报错如下 “connect: Interrupted system call”, 经过查找代码发现是在创建 socket 中执行了 connect 函数失败导致.上网查阅资料发现这 ...

    2. java 读取文件路径空格和中文的处理

      应用部署时,发生文件读取错误,发现是部署路径中含有空格的文件夹名,然后把应用服务器位置迁移了. 从网上找到如下方案:1, TestURL().class.getResource("" ...

    3. KPI绩效考核为何在国内不管用?

      很多外国很好的管理制度,到了中国都有水土不服,就像KPI绩效考核一样,到了中国执行得很不好,甚至还不如用本土的人治管理方法,那是为何呢?为什么国内学平衡计分法和KPI的热情非常高,效果却往往有限? 其 ...

    4. 用C#制作PDF文件全攻略

      用C#制作PDF文件全攻略 目  录 前    言... 3 第一部分 iText的简单应用... 4 第一章 创建一个Document 4 第一步 创建一个Document实例:... 5 第二步 ...

    5. 多条件动态LINQ 组合查询

      本文章转载:http://www.cnblogs.com/wangiqngpei557/archive/2013/02/05/2893096.html 参考:http://dotnet.9sssd.c ...

    6. SQL Server 数据库操作类

      /// <summary> /// SQLServerHelper的摘要说明. /// </summary> public class SQLServerHelper { pu ...

    7. Qt编写可换肤的中文双拼汉字输入法

      时间过得真快,不知不觉已到2015年,农历春节一眨眼就过去了,端正状态收拾心情整装待发出发. 曾经有段时间,我有一个很执着的梦想,我要导演出一部空前绝后的巨幕.不过现实无情地碾碎我的梦想,也同时将我推 ...

    8. TWaver家族新成员 — Legolas工业自动化设计平台

      对于TWaver可视化家族的成员,大家比较熟悉的是我们的网络拓扑图组件和MONO Design三维建模工具.作为开发工具,这两款产品面向广大的程序猿同志,在界面可视化上为大家省时省力.但是,当项目交付 ...

    9. 【cs229-Lecture17】离散与维数灾难

      主要内容: 解决MDP问题的算法: 离散化: 模型MDP的同化型: (model/similator) 拟合值迭代算法: Q函数: 近似政策迭代: 笔记转自:http://blog.csdn.net/ ...

    10. 测试GeoGebra博客

      已知函数 \(\textit{f}(\textit{x})=2\textit{m}\ln\textit{x}-\textit{x}^2\), \(\textit{g}(\textit{x})=\tex ...