Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

  1. Only one letter can be changed at a time
  2. 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"]
]

思路:

我自己用回溯做,结果超时了。代码和注释如下: 很长

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <stack>
#include <unordered_set>
#include <string>
using namespace std; class Solution {
public:
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
vector<vector<string>> ans;
vector<string> hash; //记录单词是否已经生成
vector<string> X;
vector<vector<string>> S;
vector<int> hashlength; //记录在k = 0 - ... 时 hash 的长度 方便弹出 int minlen = ;
int k = ;
hash.push_back(start);
hashlength.push_back();
if(S.size() <= k)
{
S.push_back(vector<string>());
}
S[k].push_back(start); while(k >= )
{
while(!S[k].empty())
{
X.push_back(S[k].back());
S[k].pop_back(); if(onedifferent(X.back(), end))
{
X.push_back(end);
if(k == minlen) //只存长度最短的
{
ans.push_back(X);
}
if(k < minlen) //如果有新的最短长度 ans清空,压入新的最短答案
{
minlen = k;
ans.clear();
ans.push_back(X);
}
}
else if(k < minlen) //k如果>= minlen 那么后面的结果肯定大于最短长度
{
k++;
if(S.size() <= k) //如果S的长度不够 扩大S长度
{
S.push_back(vector<string>());
}
if(hashlength.size() <= k)//如果hashlength的长度不够 扩大其长度
{
hashlength.push_back();
}
unordered_set<string>::iterator it;
for(it = dict.begin(); it != dict.end(); it++) //对字典中的数字遍历,得到下一个长度可以用的备选项
{
if(onedifferent(X.back(), *it) && (find(hash.begin(), hash.end(), *it) == hash.end()))
{
hashlength[k]++;
hash.push_back(*it);
S[k].push_back(*it);
}
}
}
}
k--;
while(k >= && hashlength[k]) //把当前层压入hash的值都弹出
{
hash.pop_back();
hashlength[k]--;
}
while(k >= && X.size() > k) //把当前层压入X的值弹出
{
X.pop_back();
}
} return ans;
} bool onedifferent(string s1, string s2) //判断s1是否可以只交换一次得到s2
{
int diff = ;
for(int i = ; i < s1.size(); i++)
{
if(s1[i] != s2[i])
diff++;
}
return (diff == );
}
}; int main()
{
Solution s;
unordered_set<string> dict;
dict.insert("hot");
dict.insert("dot");
dict.insert("dog");
dict.insert("lot");
dict.insert("log"); string start = "hit";
string end = "cog"; vector<vector<string>> ans = s.findLadders(start, end, dict); return ;
}

别人的思路:我没怎么看,只知道是用图的思想 速度也不快 差不多1000ms的样子

class Solution {
public:
vector<vector<string>> helper(unordered_map<string,vector<string>> &pre,string s,unordered_map<string,int>&visit,string start){
vector<vector<string> > ret,ret1;vector<string> t_ret;
if(s==start) {t_ret.push_back(s);ret.push_back(t_ret);return ret;}
for ( auto it = pre[s].begin(); it != pre[s].end(); ++it ){
ret1=helper(pre,*it,visit,start);
for(int i=;i<ret1.size();i++){
ret1[i].push_back(s);
ret.push_back(ret1[i]);
} ret1.clear();
}
return ret;
}
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
unordered_map<string,vector<string> > graph;unordered_map<string,int> visit;unordered_map<string,vector<string>> pre;
vector<vector<string> > ret; vector<string> t_ret;
if(start==end){t_ret.push_back(start);t_ret.push_back(end);ret.push_back(t_ret);return ret;}
dict.insert(start);dict.insert(end);
for ( auto it = dict.begin(); it != dict.end(); ++it ){
string t=*it; visit[t]=;
for(int i=;i<t.size();i++)
for(int j='a';j<='z';j++){
if(char(j)==t[i]) continue;
string tt=t;
tt[i]=char(j);
if(dict.count(tt)>) graph[t].push_back(tt);
}
}
queue <string> myq;
myq.push(start);
while(!myq.empty()){
for(int i=;i<graph[myq.front()].size();i++){
if( visit[graph[myq.front()][i]]==){
visit[graph[myq.front()][i]]=visit[myq.front()]+;
myq.push(graph[myq.front()][i]);
pre[graph[myq.front()][i]].push_back(myq.front());
}
else if(visit[graph[myq.front()][i]]>&&visit[graph[myq.front()][i]]>=visit[myq.front()]+){
if(visit[graph[myq.front()][i]]>visit[myq.front()]+){
visit[graph[myq.front()][i]]=visit[myq.front()]+;
pre[graph[myq.front()][i]].push_back(myq.front());
}else pre[graph[myq.front()][i]].push_back(myq.front());;
}
}
visit[start]=;
myq.pop();
}
if(visit[end]==) return ret;
ret=helper(pre,end,visit,start);
return ret;
}
};

【leetcode】Word Ladder II(hard)★ 图 回头看的更多相关文章

  1. [leetcode]Word Ladder II @ Python

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

  2. LeetCode :Word Ladder II My Solution

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

  3. LeetCode: Word Ladder II 解题报告

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

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

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

  5. LeetCode: Word Ladder II [127]

    [题目] Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) ...

  6. leetcode—word ladder II

    1.题目描述 Given two words (start and end), and a dictionary, find all shortest transformation sequence( ...

  7. [LeetCode] Word Ladder II

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

  8. LeetCode:Word Ladder I II

    其他LeetCode题目欢迎访问:LeetCode结题报告索引 LeetCode:Word Ladder Given two words (start and end), and a dictiona ...

  9. [Leetcode Week5]Word Ladder II

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

  10. 【leetcode】Word Ladder II

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

随机推荐

  1. Objective-C 【@property和@synthesize关键字】

    ------------------------------------------- @property关键字的使用及注意事项 直接上代码和注释了! // //@property关键字的使用 //① ...

  2. windows搭建virtualbox虚拟机安装的android环境

    1.首先安装virtualbox,从官网下载,安装完成之后在本地连接里面有virtualbox虚拟的网卡,可能会影响网络连接,一般禁用 2.下载android的镜像,完整名称是:android-x86 ...

  3. 慕课网上的Bootstrap学习(二)

    表单 首先<form role="form" class="form-horizontal"></form> ,创建一个水平显示的表单. ...

  4. Js中的运算符

    运算符 运算符:就是可以运算的符号 比如 + .-.*./ 运算符包括: 算术运算符 比较运算符 逻辑运算符 赋值运算符 字符串运算符 1.算术运算符 +.-.*./.%(求余数).++.-- ++: ...

  5. L003-oldboy-mysql-dba-lesson03

          L003-oldboy-mysql-dba-lesson03 IOPS:每秒钟输入输出的数量 [root@web01 ~]# cat /proc/meminfo [root@web01 ~ ...

  6. HTML5新增标签的汇总与详解

    趁着一点闲暇时间,把HTML5的新增标签整理了一下,用了表格的形式展现,分别归纳了各标签的用法及属性分析.这样方便各位以后在运用HTML5标记遇到疑惑时,直接上来对照看下就明了了,希望对大家有帮助哦. ...

  7. javascript 面向对象技术

    面向对象术语 对象 ECMA-262 把对象(object)定义为“属性的无序集合,每个属性存放一个原始值.对象或函数”.严格来说,这意味着对象是无特定顺序的值的数组. 尽管 ECMAScript 如 ...

  8. jQuery(function($){...})与(function($){...})(jQuery)知识点分享

    写jQuery插件时一些经验分享一下. 一.推荐写法 jQuery(function($){ //coding }); 全写为 jQuery(document).ready(function($){ ...

  9. 利用Google GCM发送push通知到Android客户端

    // 这个可以需要在google账号中申请,勾选gcm服务选项 $apiKey = 'AIzaSyC6h3ysrn2HDCBqONTo2vKIVVuktIFoxxx'; $headers = arra ...

  10. php header函数要点

    发布:snowfly   来源:网络     [大 中 小] 相信很多人写程序时,使用 header(location) 进行跳转往往不记得写 exit() 语句,这种做法存在严重风险. 从浏览器来看 ...