leetcode -day10 Word Ladder I II
来源:互联网 发布:mac启动引导里没os 编辑:程序博客网 时间:2024/06/03 23:03
Word Ladder
Given two words (start and end), and a dictionary, find the length of shortest transformation sequence 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"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog"
,
return its length 5
.
Note:
- Return 0 if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
分析:真的 一看这个题没有思路,想到每次改变一个字母,一直改下去,却不知道如何求最短。搜索得知,此题用到图的方法,广度优先遍历查找最短路径的方法,于是拿出《算法导论》看了一下图的广度优先遍历,大致思路是:用一个优先队列来保存访问过的点,每次取队列头元素,然后判断依次访问此元素的后继,然后将此元素出列,依次循环直到队列为空。此题相当于求最短路径,则需要判断到该结点的路径长度。
该题的思路:创建一个优先队列管理未遍历的结点,还有一个map,来保存遍历到的结点和距离。首先将start插入优先队列,然后开始循环,每次从优先队列取一个元素,并从其中删除,依次访问和此元素相差一个字母的值,查看此值是否在set中,如果不在或者在距离是否大于取出的元素的距离+1,则更新map,并插入此值,依次循环直到队列为空。
注意:其中有个很无聊的问题,看题目中转换次数为4,但是返回的长度为5,意思是加上了头尾。在执行过程中,当下面时,就显示2,不知道意思是如果start和end只有一个字母不同时,中间值无需字典中,感觉和题目要求中的Each intermediate word must exist in the dictionary不相符,很恶心。这样的话,应该在开始加一个判断start和end有几个字母不同的计算,如果为1,则直接返回2。
Input:"a", "c", ["a","b","c"]Output:3Expected:2代码如下:
class Solution {public:int ladderLength(string start, string end, unordered_set<string> &dict) {if(start.empty()||end.empty()||start.length()!=end.length()||start == end){return 0;}if(dict.empty()){return 0;}unordered_map<string,int> pathMap;pathMap.insert(make_pair(start,1));queue<string> strQue;strQue.push(start);string tempStr;while(!strQue.empty()){tempStr = strQue.front();strQue.pop();for(int i=0; i<tempStr.size(); ++i){for(char j='a'; j<='z'; ++j){if(tempStr[i] == j){continue;}else{string replaceStr = tempStr;replaceStr[i] = j;if(dict.find(replaceStr)!=dict.end() || replaceStr == end){if(!pathMap[replaceStr] || pathMap[replaceStr] && pathMap[replaceStr] > pathMap[tempStr]+1){if(replaceStr == end && pathMap[tempStr]+1 < 2){continue;}pathMap[replaceStr] = pathMap[tempStr]+1;strQue.push(replaceStr);}}}}}}return pathMap[end];}};
2、Word Ladder II
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.
分析:这个题和上题很像,但是特别复杂,我采用上次的思路,添加了一个unordered_map<string,vector<string>> prevStrVec来保存前缀,前缀都是从start到key的最短路径上的前一个词,然后再根据end向前追溯一直到start,每一条路径就是保存的路径,思路感觉没有问题,本地跑几个小数据也是对的,就是一直出错。
首次出错为:Output Limit Exceeded
输出超过限制,就是可能中间出现的循环折叠,没找到问题,然后设置了长度递归限制,当路径超过最短路径值时返回,此时又出错:
Time Limit Exceeded
大数据时,显示超时
代码如下:超时的代码:
class Solution {public:vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) {//vector<vector<string> > paths;if(start.empty()||end.empty()||start.length()!=end.length()||start == end){return paths;}if(dict.empty()){return paths;}swap(start,end);unordered_map<string,int> pathMap;pathMap.insert(make_pair(start,1));queue<string> strQue;strQue.push(start);string tempStr;unordered_map<string,vector<string>> prevStrVec;while(!strQue.empty()){tempStr = strQue.front();strQue.pop();for(int i=0; i<tempStr.size(); ++i){for(char j='a'; j<='z'; ++j){if(tempStr[i] == j){continue;}else{string replaceStr = tempStr;replaceStr[i] = j;if(dict.find(replaceStr)!=dict.end() || replaceStr == end){if(!pathMap[replaceStr] || pathMap[replaceStr] && pathMap[replaceStr] >= pathMap[tempStr]+1){if(replaceStr == end && pathMap[tempStr]+1 < 2){continue;}if(pathMap[replaceStr] && pathMap[replaceStr] > pathMap[tempStr]+1){prevStrVec[replaceStr].clear();}prevStrVec[replaceStr].push_back(tempStr);pathMap[replaceStr] = pathMap[tempStr]+1;strQue.push(replaceStr);}}}}}}if(pathMap[end]){vector<string> tempVec;tempVec.push_back(end);int shortLength = pathMap[end];findPaths(end,prevStrVec,tempVec,shortLength);}return paths;}void findPaths(string& end,unordered_map<string,vector<string>> &prevStrVec,vector<string> &path,int shortLength){vector<string> preEndVec = prevStrVec[end];if(preEndVec.empty()){paths.push_back(path);return;}if(path.size()==shortLength){return;}for(int j=0; j<preEndVec.size(); ++j){string preStr = preEndVec[j];vector<string> tempPath = path;tempPath.push_back(preStr);findPaths(preStr,prevStrVec,tempPath,shortLength);}}vector<vector<string> > paths;};
改进,上述和第一题的区别是pathMap[replaceStr] 和pathMap[tempStr]+1 比较时,一个是>,一个是>=,后者将==的部分也放入队列了,这样时间复杂度高了好多,改进,==时不将数据放入队列,Accepted。
代码如下:
class Solution {public:vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) {//vector<vector<string> > paths;if(start.empty()||end.empty()||start.length()!=end.length()||start == end){return paths;}if(dict.empty()){return paths;}swap(start,end);unordered_map<string,int> pathMap;pathMap.insert(make_pair(start,1));queue<string> strQue;strQue.push(start);string tempStr;unordered_map<string,vector<string>> prevStrVec;while(!strQue.empty()){tempStr = strQue.front();strQue.pop();for(int i=0; i<tempStr.size(); ++i){for(char j='a'; j<='z'; ++j){if(tempStr[i] == j){continue;}else{string replaceStr = tempStr;replaceStr[i] = j;if(dict.find(replaceStr)!=dict.end() || replaceStr == end){if(!pathMap[replaceStr] || pathMap[replaceStr] && pathMap[replaceStr] >= pathMap[tempStr]+1){if(replaceStr == end && pathMap[tempStr]+1 < 2){continue;}if(pathMap[replaceStr] && pathMap[replaceStr] > pathMap[tempStr]+1){prevStrVec[replaceStr].clear();}else if(pathMap[replaceStr] && pathMap[replaceStr] == pathMap[tempStr]+1){ prevStrVec[replaceStr].push_back(tempStr); continue;}pathMap[replaceStr] = pathMap[tempStr]+1;strQue.push(replaceStr);prevStrVec[replaceStr].push_back(tempStr);}}}}}}if(pathMap[end]){vector<string> tempVec;tempVec.push_back(end);int shortLength = pathMap[end];findPaths(end,prevStrVec,tempVec,shortLength);}pathMap.clear();return paths;}void findPaths(string& end,unordered_map<string,vector<string>> &prevStrVec,vector<string> &path,int shortLength){vector<string> preEndVec = prevStrVec[end];if(preEndVec.empty()){paths.push_back(path);return;} if(path.size()==shortLength){ return; }for(int j=0; j<preEndVec.size(); ++j){string preStr = preEndVec[j];vector<string> tempPath = path;tempPath.push_back(preStr);findPaths(preStr,prevStrVec,tempPath,shortLength);}}vector<vector<string> > paths;};
- leetcode -day10 Word Ladder I II
- 【LeetCode】word ladder I&& II
- Leetcode 127. Word Ladder I & 126. Word Ladder II
- Word Ladder I && II
- 【leetcode】Word Ladder II
- [LeetCode]Word Ladder II
- [leetcode] Word Ladder II
- LeetCode - Word Ladder II
- Leetcode: Word Ladder II
- leetcode Word Ladder II
- Leetcode Word Ladder II
- LeetCode | Word Ladder II
- leetcode word ladder II
- 【Leetcode】Word Ladder II
- [LeetCode] Word Ladder II
- Word Ladder II -- LeetCode
- Leetcode: Word Ladder II
- leetcode-Word Ladder II
- latch: cache buffers chains故障处理总结
- 题目1021:统计字符
- win7中如何设置任务计划程序
- GNU Libtool 的用途及基本使用方法
- js学习小结(八)2014.5.6(DOM节点,DOM操作技术)
- leetcode -day10 Word Ladder I II
- 安装Rational Rose启动报错:无法启动此程序,因为计算机中丢失 suite objects.dll。
- 新人如何做产品经理
- codechef Little Elephant and Bombs题解
- POJ3714 最近点对
- 电子商务
- ExtJS4+SSH 实现Excel导出
- 解决开机出现“CLIENT MAC ADDR”的问题
- jubuntu cannot open vitualbox