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.

题解:算是leetcode最恶心的一道题了。

Word Ladder一样要用BFS来搜索,但是要解决的问题是如何在BFS中保存路径。我们知道在DFS中 保存路径十分简单,但是在BFS中就很麻烦了。因为我们把点一层一层的放在队列里面,而不是一次把一条路径搜索完全。所以这里引进一种新的类Node如下:

class Node{
ArrayList<Node> prev;
String me;
int dist;
public Node(String me,int dist){
this.me = me;
this.prev = null;
this.dist = dist;
}
}

使用该类,我们把搜索路径上遇到的每一个单词看成一个节点,me保存该节点对应的单词,dist保存从start单词搜索到该单词的最短距离,prev保存从start到该节点所有长度为dist的路径上该节点的前驱节点。

这样我们就可以在完成BFS后,从最后一个节点endNode(endNode对应单词end),利用前驱节点信息DFS出startNode到endNode的所有路径了。函数findPath实现这个功能。

另外在BFS的时候,我们需要一个map,来记录当前访问过哪些单词以及它们对应的节点。假设当前访问的节点是node,它对应的单词是t,我们通过修改t的每一位字母生成新的单词,如果新的单词在dict中且没有建立相应的节点(在map中没有记录),那么就建立相应的节点,并把该节点和单词的对应信息保存在map里面;如果当前生成的单词在dict中且已经有相应的节点,那么我们就看是否node也是它的前驱,如果是,把node加入它的前驱列表就可以了。

结束的条件是,我们生成了一个单词,它正好等于end,说明找到了从start到end的一条路径(不过为了找到所有到end的路径,所以当前队列中的元素还是要遍历完,因为它们在同一层上,也有可能可以达到end,所以用一个stop变量控制最外层的大循环);或者队列为空,说明找不到从start到end的路径。

最后代码如下:

 public class Solution {
private List<List<String>> answer= new ArrayList<List<String>>();
class Node{
ArrayList<Node> prev;
String me;
int dist;
public Node(String me,int dist){
this.me = me;
this.prev = null;
this.dist = dist;
}
}
private void findPath(Node endNode,ArrayList<String> result,String start){
if(endNode.me.equals(start)){
ArrayList<String> temp= new ArrayList<String>(result);
answer.add(temp);
return;
}
for(Node n:endNode.prev){
result.add(0, n.me);
findPath(n, result, start);
result.remove(0);
}
}
public List<List<String>> findLadders(String start, String end, Set<String> dict) { if(start == end){
List<String> result = new ArrayList<String>();
result.add(start);
result.add(end);
answer.add(result);
return answer;
} Queue<Node> queue = new LinkedList<Node>();
HashMap<String, Node> map = new HashMap<String,Node>(); Node startNdoe = new Node(start,0);
queue.add(startNdoe);
map.put(start, startNdoe);
Node endNode = null;
int strLen = start.length();
boolean stop = false; while(!queue.isEmpty() && !stop){
int thisLevel = queue.size();
for(int i = 0;i < thisLevel;i++){
Node node = queue.poll();
for(int j = 0;j < strLen;j++){
StringBuilder t = new StringBuilder(node.me);
char ch_t = node.me.charAt(j);
for(char k = 'a';k <= 'z';k++){
if(k != ch_t){
t.setCharAt(j, k);
if(dict.contains(t.toString())){
Node v = map.get(t.toString());
if(v == null){
Node tempNode = new Node(t.toString(),node.dist+1);
tempNode.prev = new ArrayList<Node>();
tempNode.prev.add(node);
queue.add(tempNode);
map.put(t.toString(), tempNode);
if(t.toString().equals(end)){
endNode = tempNode;
stop = true;
}
}
else {
if(v.dist == node.dist+1)
v.prev.add(node);
}
}
}
}
}
}
}
if(endNode != null){
ArrayList<String> result = new ArrayList<String>();
result.add(endNode.me);
findPath(endNode,result,start);
}
return answer;
}
}

【leetcode刷题笔记】Word Ladder II的更多相关文章

  1. 【leetcode刷题笔记】Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  2. 【leetcode刷题笔记】Subsets II

    Given a collection of integers that might contain duplicates, S, return all possible subsets. Note: ...

  3. 【leetcode刷题笔记】N-Queens II

    Follow up for N-Queens problem. Now, instead outputting board configurations, return the total numbe ...

  4. LeetCode刷题笔记和想法(C++)

    主要用于记录在LeetCode刷题的过程中学习到的一些思想和自己的想法,希望通过leetcode提升自己的编程素养 :p 高效leetcode刷题小诀窍(这只是目前对我自己而言的小方法,之后会根据自己 ...

  5. LeetCode刷题笔记 - 12. 整数转罗马数字

    学好算法很重要,然后要学好算法,大量的练习是必不可少的,LeetCode是我经常去的一个刷题网站,上面的题目非常详细,各个标签的题目都有,可以整体练习,本公众号后续会带大家做一做上面的算法题. 官方链 ...

  6. 18.9.10 LeetCode刷题笔记

    本人算法还是比较菜的,因此大部分在刷基础题,高手勿喷 选择Python进行刷题,因为坑少,所以不太想用CPP: 1.买股票的最佳时期2 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. ...

  7. Leetcode刷题笔记(双指针)

    1.何为双指针 双指针主要用来遍历数组,两个指针指向不同的元素,从而协同完成任务.我们也可以类比这个概念,推广到多个数组的多个指针. 若两个指针指向同一数组,遍历方向相同且不会相交,可以称之为滑动窗口 ...

  8. 【leetcode刷题笔记】Length of Last Word

    Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the l ...

  9. 【leetcode刷题笔记】Palindrome Partitioning II

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

随机推荐

  1. 2017 Wuhan University Programming Contest (Online Round) B Color 树形dp求染色方法数

    /** 题目:Color 链接:https://oj.ejq.me/problem/23 题意:给定一颗树,将树上的点最多染成m种颜色,有些节点不可以染成某些颜色.相邻节点颜色不同.求染色方法数. 思 ...

  2. 放苹果(整数划分变形题 水)poj1664

    问题:把M个相同的苹果放在N个相同的盘子里.同意有的盘子空着不放,问共同拥有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法. 例子 : 1 7 3 ---------------8 ...

  3. VLC Web插件的浏览器兼容性

    网页插件实现原理 IE浏览器基于Activex插件来实现,非IE浏览器采用NPAPI来实现,所以,非浏览器需要支持NPAPI来实现. IE浏览器 FF浏览器(版本小于52) 原因从 Firefox 版 ...

  4. 第一百八十五节,jQuery,Ajax 表单插件

    jQuery,Ajax 表单插件 学习要点: 1.核心方法 2.option 参数 3.工具方法 传统的表单提交,需要多次跳转页面,极大的消耗资源也缺乏良好的用户体验.而这款 form.js 表单的 ...

  5. window linux IPC ftok BY_HANDLE_FILE_INFORMATION

    看这题目就很乱,心情当然也是不怎么美好了.前一段时间做了一个项目,AIX(Unix的一种)中的一个系统向WINDOWS移植,开发环境由IBM的C/C++(叫什么忘记了,好像是xlC)变为VC++. 这 ...

  6. 项模板选择器属性(ItemTemplateSelector属性)和样式选择器(ItemContainerStyleSelector)

    3.4.5 共享尺寸组 样式选择器: 或者========================================

  7. JavaScript 变量,数据类型

    这篇笔记呢,咱记录下变量和数据类型的基础知识,因为两者有联系 所以放在一起记录 1 如何声明变量 变量声明使用var关键字,下面举一些变量声明的例子: <!DOCTYPE html> &l ...

  8. tomcat访问日志分析

    常使用web服务器的朋友大都了解,一般的web server有两部分日志: 一是运行中的日志,它主要记录运行的一些信息,尤其是一些异常错误日志信息 二是访问日志信息,它记录的访问的时间,IP,访问的资 ...

  9. 《从零开始学Swift》学习笔记(Day 52)——Cocoa错误处理模式

    原创文章,欢迎转载.转载请注明:关东升的博客 Swift错误处理模式,在Swift 1.x和Swift 2.0是不同的两种模式. Swift 1.x代码错误处理模式采用Cocoa框架错误处理模式,到现 ...

  10. 用户画像 销量预测 微观 宏观 bi

    w 目前我们没有自己的平台 第三方平台又不会给任何我们想要的数据   没有用户的注册信息 全天候的行为信息   用户画像没法做    针对我们业务的bi做的思路是什么呢   数据中心怎么做销量预测呢 ...