这道题非常难。

之前的题目我提到过一次用两个vector来做层序遍历的,就是由于这道题。要想最后恢复出单词变换的路径,就须要事先保存,依据dp中路径恢复的启示,保存的应该是一个单词的前一个变换节点。可能有非常多个单词都能变换到当前单词,因此应该是一个set。用一个二维的vector保存当前能够变换到的单词和变换出这些单词单词。每一维的vector存放的都是一个set。设存放当前可訪问单词的vector下标是current,存放变幻出这些单词的vector下标是pre,那么每一轮要開始更新current之前,都要从字典里删除pre中存放的单词。这样做比直接用一个set存放訪问过的单词要快,也更加节省空间,由于字典的规模在不断变小。由于要打印出所有的路径,所以不是说遇到目标单词就直接结束,而应该等着这一层的变换所有结束之后才行。假设在这一层变换之后发现了目标单词,那么就開始打印路径。

递归打印路劲跟其它题目的写法没有太多不同,主要是注意假设用引用做的话要合适的回退,且最后是反向打印的,应该把结果reverse一下再放到结果集中。

实现的时候还发现一个问题,我之前一直以为在訪问方面vector应该是最快的,所以就把全部东西都弄成了vector,然后下标訪问,结果超时了。假设要顺序訪问的话,迭代器要比随机訪问好。

class Solution {
public:
vector<vector<string> > res;
void getPaths(unordered_map<string, vector<string> > &predict, vector<string> &tpres, string &word){
if(predict[word].size() == 0){
tpres.push_back(word);
vector<string> pres = tpres;
reverse(pres.begin(), pres.end());
res.push_back(pres);
tpres.pop_back();
return;
}
tpres.push_back(word);
for(auto it=predict[word].begin();it!=predict[word].end();++it)
getPaths(predict, tpres, *it);
tpres.pop_back();
}
vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) {
unordered_map<string, vector<string> > predict;
int cu = 0, pre = 1, len = start.length();
vector<unordered_set<string> > candi(2);
vector<string> tpres;
predict[start] = tpres;
candi[0].insert(start);
string word;
while(true){
cu = !cu;
pre = !pre;
for(auto it=candi[pre].begin();it!=candi[pre].end();++it){
dict.erase(*it);
}
candi[cu].clear();
for(auto it=candi[pre].begin();it!=candi[pre].end();++it){
for(int pos=0;pos<len;pos++){
word = *it;
for(char c='a';c<='z';c++){
if(word[pos] == c) continue;
word[pos] = c;
if(dict.count(word)>0){
candi[cu].insert(word);
predict[word].push_back(*it);
}
}
}
}
if(candi[cu].size() == 0) return res;
if(candi[cu].count(end))
break;
}
getPaths(predict, tpres, end);
return res;
}
};

leetcode第一刷_Word Ladder II的更多相关文章

  1. leetcode第一刷_Path Sum II

    在更新上面一道题的时候我就想,是不是另一道打印路径的,果不其然啊. 这样的题非经常见的,做法也非常easy,我是用一个引用的vector来存,满足条件之后直接压入结果集中,当然也能够用数组之类的,都一 ...

  2. leetcode第一刷_Spiral Matrix II

    跟上一题的策略全然一样,这个题是要求保存当前增加的是第几个数,由于矩阵里面存的就是这个东西. 我有尝试想过是不是有一种方法能够直接推算出每一行的数据是哪些.但没过多久就放弃了.这样的方法尽管能够避免在 ...

  3. leetcode第一刷_Jump Game II

    要求最小的步数,是不是非常easy想到用dp啊? 我一開始的做法是,当找到了一个可以从它延伸到更远的位置,就把这个位置和最远位置的步数都更新一下,结果超时了. 事实上这样不仅是超时的,并且是错误的.由 ...

  4. leetcode第一刷_Word Search

    这道题之前一直没敢做,没想到前天用递归一遍过了. . 当时为什么想着用递归,而不是dp呢.由于我想到达某个位置的情况有非常多,即使从当前位置開始的搜索是已知的,但之前的状态是如何的也无从得知啊,实话实 ...

  5. leetcode第一刷_Permutations II

    当有反复元素的时候呢? 不用拍脑袋都会想到一种方法,也是全部有反复元素时的通用处理方法,维护一个set,假设这个元素没增加过就增加,增加过了的忽略掉.可是,在这道题上这个通用方法竟然超时了! 怎么办? ...

  6. leetcode第一刷_Populating Next Right Pointers in Each Node II

    很自然的推广,假设去掉全然二叉树的条件呢?由于这个条件不是关键,因此不会影响整体的思路.做法依旧是每次找到一层的起点,然后一层一层的走. 假设是全然二叉树的话,每层的起点就是上一层起点的左孩子,兄弟之 ...

  7. leetcode第一刷_Combination Sum Combination Sum II

    啊啊啊啊.好怀念这样的用递归保存路径然后打印出来的题目啊.好久没遇到了. 分了两种,一种是能够反复使用数组中数字的,一种是每一个数字仅仅能用一次的.事实上没有多大差别,第一种每次进入递归的时候都要从头 ...

  8. leetcode第一刷_N-Queens II

    这个题好无趣,竟然输出解的个数.前一个题把全部解都输出出来了.还愁不知道解的个数吗. . 我怀疑这个解的个数是有一个类似通项的东西,就上网查了一下.没有啊亲,最后就把上一题的代码略微改了一下过掉了. ...

  9. leetcode第一刷_Best Time to Buy and Sell Stock II

    这道题尽管是上一道题的增强.可是反而简单了. 能够交易无数次,可是买卖必须成对的出现. 为了简单起见.我用abc三股股票来说明,且忽略掉相等的情况.三个数一共同拥有六种大小关系.注意他们之间的先后顺序 ...

随机推荐

  1. (多对象)Json转换成List

    写的不好,请大家见谅. 1.Json 格式{"packages":[{“type”:”aaa”}],"zone_packages":[{"ticket ...

  2. HTML5 文件域+FileReader 读取文件(一)

    在HTML5以前,HTML的文件上传域的功能具有很大的局限性,这种局限性主要体现在如下两点: 每次只能选择一个文件进行上传 客户端代码只能获取被上传文件的文件路径,无法访问实际的文件内容 一.File ...

  3. 【转】那些好用的iOS开发工具

    原文:http://www.devtang.com/blog/2014/06/29/ios-dev-tools/ 前言 从苹果发明iPhone起,AppStore上的一个又一个类似flappy bir ...

  4. jQuery 的ready事件和 JavaScript 的load事件对比

    为了理解2个事件的异同,先了解一下HTML文档加载顺序 HTML DOM文档加载步骤 HTML DOM文档加载是按顺序执行的,这与浏览器的渲染方式有关,一般浏览器渲染操作的顺序大致按如下几个步骤 1, ...

  5. java获取天气信息

    通过天气信息接口获取天气信息,首先要给项目导入程序所需要的包,具体需要如下几个包: json-lib-2.4.jar ezmorph-1.0.6.jar commons-beanutils-1.8.3 ...

  6. 在jQuery.getData中renderCallback使用不同创建方式的结果

    JavaScript 中需要创建函数的话,有两种方法:函数声明.函数表达式,各自写法如下:// 方法一:函数声明function foo() {}// 方法二:函数表达式var foo = funct ...

  7. linux命令——Grep 命令 用法大全

    1. 参数: -I :忽略大小写 -c :打印匹配的行数 -l :从多个文件中查找包含匹配项 -v :查找不包含匹配项的行 -n:打印包含匹配项的行和行标 2.RE(正则表达式) \ 忽略正则表达式中 ...

  8. 写给新手看的Flask+uwsgi+Nginx+Ubuntu部署教程

    学习 Flask,写完一个 Flask 应用需要部署的时候,就想着折腾自己的服务器.根据搜索的教程照做,对于原理一知半解,磕磕碰碰,只要运行起来了,谢天谢地然后不再折腾了,到下一次还需要部署时,这样的 ...

  9. POJ - 3903 Stock Exchange(LIS最长上升子序列问题)

    E - LIS Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u   Descripti ...

  10. C题

    C - C Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu   Description   Ass ...