leetcode第一刷_Word Ladder II
这道题非常难。
之前的题目我提到过一次用两个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的更多相关文章
- leetcode第一刷_Path Sum II
在更新上面一道题的时候我就想,是不是另一道打印路径的,果不其然啊. 这样的题非经常见的,做法也非常easy,我是用一个引用的vector来存,满足条件之后直接压入结果集中,当然也能够用数组之类的,都一 ...
- leetcode第一刷_Spiral Matrix II
跟上一题的策略全然一样,这个题是要求保存当前增加的是第几个数,由于矩阵里面存的就是这个东西. 我有尝试想过是不是有一种方法能够直接推算出每一行的数据是哪些.但没过多久就放弃了.这样的方法尽管能够避免在 ...
- leetcode第一刷_Jump Game II
要求最小的步数,是不是非常easy想到用dp啊? 我一開始的做法是,当找到了一个可以从它延伸到更远的位置,就把这个位置和最远位置的步数都更新一下,结果超时了. 事实上这样不仅是超时的,并且是错误的.由 ...
- leetcode第一刷_Word Search
这道题之前一直没敢做,没想到前天用递归一遍过了. . 当时为什么想着用递归,而不是dp呢.由于我想到达某个位置的情况有非常多,即使从当前位置開始的搜索是已知的,但之前的状态是如何的也无从得知啊,实话实 ...
- leetcode第一刷_Permutations II
当有反复元素的时候呢? 不用拍脑袋都会想到一种方法,也是全部有反复元素时的通用处理方法,维护一个set,假设这个元素没增加过就增加,增加过了的忽略掉.可是,在这道题上这个通用方法竟然超时了! 怎么办? ...
- leetcode第一刷_Populating Next Right Pointers in Each Node II
很自然的推广,假设去掉全然二叉树的条件呢?由于这个条件不是关键,因此不会影响整体的思路.做法依旧是每次找到一层的起点,然后一层一层的走. 假设是全然二叉树的话,每层的起点就是上一层起点的左孩子,兄弟之 ...
- leetcode第一刷_Combination Sum Combination Sum II
啊啊啊啊.好怀念这样的用递归保存路径然后打印出来的题目啊.好久没遇到了. 分了两种,一种是能够反复使用数组中数字的,一种是每一个数字仅仅能用一次的.事实上没有多大差别,第一种每次进入递归的时候都要从头 ...
- leetcode第一刷_N-Queens II
这个题好无趣,竟然输出解的个数.前一个题把全部解都输出出来了.还愁不知道解的个数吗. . 我怀疑这个解的个数是有一个类似通项的东西,就上网查了一下.没有啊亲,最后就把上一题的代码略微改了一下过掉了. ...
- leetcode第一刷_Best Time to Buy and Sell Stock II
这道题尽管是上一道题的增强.可是反而简单了. 能够交易无数次,可是买卖必须成对的出现. 为了简单起见.我用abc三股股票来说明,且忽略掉相等的情况.三个数一共同拥有六种大小关系.注意他们之间的先后顺序 ...
随机推荐
- 动态插入图片到 svg 中
动态插入图片到 svg 中使用 createElementNS 来创建svg标签,通过setAttributeNS 来设置属性, 要注意两点,创建的时候要有'http://www.w3.org/200 ...
- python自学笔记
python自学笔记 python自学笔记 1.输出 2.输入 3.零碎 4.数据结构 4.1 list 类比于java中的数组 4.2 tuple 元祖 5.条件判断和循环 5.1 条件判断 5.2 ...
- SpringMVC简单搭建与入门
SpringMVC框架是spring框架的一个模块.springmvc和spring无需要通过中间整合层进行整合. 学习的时候,先了解一下流程至关重要,下面,简单介绍一下流程. 源码下载:http:/ ...
- 自定义Back返回键(实现按两次返回键退出程序)
实现机制:当用户点击物理返回键时,Activity会调用onBackPressed(),只需在Activity中复写该方法即可 以下是代码实现: package com.example.qjm3662 ...
- javascript读取xml的方法【转载】
jquery读取xml文件 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...
- [UML]UML中几种类间关系
UML中类间关系主要有六种,分别是继承.实现.依赖.关联.聚合.组合 1.继承 继承是指A类继承B类,继承它private除外的所有属性和方法,这种关系是最常见的关系,在java中使用extends表 ...
- 省队集训day6 B
一道AC自动机题···· 一定要把一个节点没有的儿子接到它fai的儿子,否则会卡到n^2的······· #include<cstdio> #include<iostream> ...
- java web 组件Listenter(一)
JavaWeb中监听器的事件源(ServletContext.HttpSession.ServletRequest.JavaBean) 1.ServletContext 生命周期监听:ServletC ...
- Solr4.8.0源码分析(18)之缓存机制(一)
Solr4.8.0源码分析(18)之缓存机制(一) 前文在介绍commit的时候具体介绍了getSearcher()的实现,并提到了Solr的预热warn.那么本文开始将详细来学习下Solr的缓存机制 ...
- Andoird 监听开机广播和关机广播
需求:有时候,我们需要自己的程序在开机后自动运行;在关机时,记录一些信息到文件中. 一.开机广播监听Android系统启动完成后会自动发出启动完成广播(android.intent.action.BO ...