题目:

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. UICollectionView瀑布流的实现原理(转)

      http://ios.jobbole.com/85689/ 和使用 UIScollView 创刊一个瀑布流是一样的方式 7cc829d3gw1f4nq2oc09zj20j00hvq90.jpg 我的 ...

    2. windows原生开发之界面疑云

          windows桌面开发,界面始终是最大的困惑.我们对前端工具的要求,其实只有窗体设计器.消息映射,过分点的话自适应屏幕.模型绑定.能够免于手工书写,其实这个问题并不复杂,但VS不实现.QT语法 ...

    3. git第一次提交代码到远程仓库

      博客搬家了,本文新地址:http://www.zicheng.net/article/4 感谢支持 本操作说明是先有代码,后来创建git仓库,然后把本地代码提交到远程仓库的操作步骤: 1.初始化 在当 ...

    4. 大型网站系统架构演化之路【mark】

      前言 一 个成熟的大型网站(如淘宝.天猫.腾讯等)的系统架构并不是一开始设计时就具备完整的高性能.高可用.高伸缩等特性的,它是随着用户量的增加,业务功能的 扩展逐渐演变完善的,在这个过程中,开发模式. ...

    5. 【转】mac/linux终端光标的快捷键操作

      摘自网络:原标题是类似linux/unix命令行终端的光标及字符控制快捷键的东东. 常用的快捷键: Ctrl + d 删除一个字符,相当于通常的Delete键(命令行若无所有字符,则相当于exit:处 ...

    6. Android开发(51) 摄像头自动对焦。在OpenCV图像识别中连续拍照时自动对焦和拍照。

      概述 对焦,这里所说的“焦”是指“焦距”.在拍照时,一定是需要调焦的.一般会在目标位置最清晰的时候会停止对焦.最近在处理OpenCV进行图像识别时,需要连续的调焦(对焦),并在对焦完成后进行拍照,获取 ...

    7. Cocos2d-JS项目之四:UI界面的优化

      测试环境: iphone4.iOS6.1.2.chrome 37.2062.60,Cocos2d-js 3.6 之前写了不少,实际项目也按这个去优化了,也有效果,但到最后才发现,尼玛,之前都搞错了,之 ...

    8. CSS - Select 标签在不同浏览器中的高度设置

      当使用Select标签时,在不同浏览器中显示的高度不同,如何解决此问题: 解决方法链接:http://stackoverflow.com/questions/20477823/select-html- ...

    9. saiku之行速度优化(三)

      经历了前两轮优化之后,saiku由不可使用,优化到可以使用,不过在分析大量日志数据的时候,还有顿卡的感觉!继续观察背后执行的Sql,决定将注意力关注到索引上面! 日志的主要使用场景是:固定日期维度的数 ...

    10. git 在提交之前撤销add操作

      问题 在使用git时,在未添加.ignore文件前使用 git add . 将所有文件添加到库中,不小心将一些不需要加入版本库的文件加到了版本库中.由于此时还没有提交所以不存在HEAD版本,不能使用 ...