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"]
]

 

Note:

  • All words have the same length.
  • All words contain only lowercase alphabetic characters.

难度挺高的一题。沿用Word Ladder I的思路,此题本质也是图的遍历问题,求的是从给定起点到给定终点之间的所有最短路径。

Word Ladder I 中,找到一条合法路径即返回。然而此题中找到一条之后还需要进行讨论,问题就变复杂了,因为广度优先遍历中之前的节点都已经出队列没法再获取到。

所以,沿用Word Ladder I中的思想,不仅记录每个结点距离start的距离,而且用List记录这个到达这个节点的所有最短路径上的前驱结点。举个例子:

6的List应当为 2 和 3, 因为5 不是最短路径上的点。

这里采用HashMap去处理结点和List的映射关系。

这样在进行广度优先遍历过程中,会有以下几种情况:

1. 相邻结点新结点,那么新结点入队列;建立新结点的List和,把当前结点加入到新结点的List中;记录新结点的最短路径长度为当前结点的最短路径长度L+1

2. 相邻结点在队列中(例如上图结点3出队列时,6还在队列中)且相邻结点的最短路径长度=当前结点最短路径长度+1,那么说明是另一条最短路径,只需要把当前结点加入到相邻结点的List中。

3. 相邻结点在队列中且相邻结点的最短路径长度<当前结点最短路径长度+1,说明这条不是最短路径,那么什么也不做,当前结点默默出队列。

这样我们可以得到从start到end的若干条链,从end开始逆向使用回溯法记录所有的链上的结点即可。

代码如下:

     HashMap<String, ArrayList<String>> nodeSet = new HashMap<String, ArrayList<String>>();
public List<List<String>> findLadders(String start, String end, Set<String> dict) {
List<List<String>> re = new ArrayList<List<String>>();
Queue<String> q = new LinkedList<String>();
HashSet<String> hs = new HashSet<String>();
HashMap<String, Integer> dist = new HashMap<String, Integer>();
q.add(start);
nodeSet.put(start, new ArrayList<String>());
nodeSet.put(end, new ArrayList<String>());
dist.put(start, 1); while(!q.isEmpty()) {
String temp = q.poll();
int l = dist.get(temp);
hs.add(temp);
for(int i=0;i<temp.length();i++) {
for(char c='a';c<='z';c++) {
if(temp.charAt(i)==c)
continue;
StringBuilder sb = new StringBuilder(temp);
sb.setCharAt(i,c);
String next = sb.toString();
if(next.equals(end)) {
if(!dist.containsKey(end)) {
dist.put(end,l+1);
nodeSet.get(end).add(temp);
}
else if(dist.get(end)==l+1)
nodeSet.get(end).add(temp);
}
else if(dict.contains(next) && !hs.contains(next)) {
if(!dist.containsKey(next)) {
q.add(next);
dist.put(next, l+1);
ArrayList<String> arr = new ArrayList<String>();
arr.add(temp);
nodeSet.put(next, arr);
} else if(dist.get(next)==l+1)
nodeSet.get(next).add(temp);
}
}
}
}
List<String> path = new ArrayList<String>();
path.add(end);
collect(start,re,path,nodeSet.get(end));
return re;
}
public void collect(String start, List<List<String>> re, List<String> path, ArrayList<String> prevNodes)
{
for(int i=0;i<prevNodes.size();i++)
{
path.add(0,prevNodes.get(i));
if(prevNodes.get(i).equals(start)) {
List<String> pathCopy = new ArrayList<String>(path);
re.add(pathCopy);
}
else
collect(start,re,path,nodeSet.get(prevNodes.get(i)));
path.remove(0);
}
}

[Leetcode][JAVA] Word Ladder II的更多相关文章

  1. Java for LeetCode 126 Word Ladder II 【HARD】

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

  2. LeetCode 126. Word Ladder II 单词接龙 II(C++/Java)

    题目: Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transfo ...

  3. [Leetcode Week5]Word Ladder II

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

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

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...

  5. 【leetcode】Word Ladder II

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

  6. [LeetCode#128]Word Ladder II

    Problem: Given two words (start and end), and a dictionary, find all shortest transformation sequenc ...

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

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...

  8. leetcode 126. Word Ladder II ----- java

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...

  9. Leetcode#126 Word Ladder II

    原题地址 既然是求最短路径,可以考虑动归或广搜.这道题对字典直接进行动归是不现实的,因为字典里的单词非常多.只能选择广搜了. 思路也非常直观,从start或end开始,不断加入所有可到达的单词,直到最 ...

随机推荐

  1. httperf学习笔记(CentOS-6.6环境下安装配置)

    新工作已经找到了,最近在忙着熟悉环境,昨天领导让我接触下httperf压力测试工具 百度了下,相关的文档,准备着手配置一个测试环境基于linux系统httperf+autobench+gnuplot, ...

  2. aspx中如何绑定llistbox数据列表

    DataTable dt = new DataTable(); dt = goodsbll.Get_prodtolist(_fatherpeoid,_sonpeoid).Tables[]; ) { f ...

  3. 关于Reflow回流

    在CSS规范中有一个渲染对象的概念,通常用一个盒子(box, rectangle)来表示.mozilla通过一个叫frame的对象对盒子进行操作.frame主要的动作有三个: 构造frame, 以建立 ...

  4. Thinkphp源码分析系列(二)–引导类

    在上一章我们说到,ThinkPHP.php在设置完框架所需要的变量和调教好环境后,在最后调用了  Think\Think::start();  即Think命名空间中的Think类的静态方法start ...

  5. Fliwer:监控植物状态 实现远程浇水

    Fliwer是一款针对植物而研发出来的设备,可以监控土壤水分.光照.温度.空气湿度和肥料是否充足这些指标.结合云端的植物数据和天气预报,它能够自动决定什么时候给植物浇水,甚至提醒你什么时候应该施肥.修 ...

  6. webForm中dropDownList的一些用法

    DropDownList 控件用于创建下拉列表. DropDownList 控件中的每个可选项都是由 ListItem 元素定义的! 该控件支持数据绑定! DropDownList1.DataSour ...

  7. 64位Win7下运行ASP+Access网站的方法

    64位Win7下运行ASP+Access网站的方法 近日系统升级为WIN7 64位之后,突然发现原本运行正常的ASP+ACCESS网站无法正常连接数据库. 网上搜索多次,终于解决了问题,总结了几条经验 ...

  8. dynamic2016 crm 安装语言包提示缺少组件报错

    当安装dynamic2016 CRM英文语言包安装成功后,在系统切换语言的时候提示如下报错为缺少CRM reporting extensions 插件导致,在CRM的解压安装包如下路径找到对应的执行文 ...

  9. linux--分卷压缩解压缩

    1.先压缩目录为一个文件 root@ip# tar zcvf apk.tar apk/ 2.对文件进行切分,-d表示切分后的文件后缀已数字区分(如apk_2015.tar01,apk_2015.tar ...

  10. Java 技术体系图

    Java 程序员 高级特性 反射.泛型.注释符.自动装箱和拆箱.枚举类.可变 参数.可变返回类型.增强循环.静态导入 核心编程 IO.多线程.实体类. 集合类.正则表达式. XML 和属性文件 图形编 ...