[leetcode-126]Word Ladder II(java)
2015-09-04 22:03
591 查看
问题描述:这里写链接内容
分析:这道题首先要找到最短路径,最短路径是采用BFS方法,之前侯大神给我讲的时候说,为什么BFS找到的节点是最短的,因为BFS搜索过程是类似于波浪型的,一层一层荡出去,这样只要找到了结束点,这个店就一定是最短路径。
但是这道题要求把路径找出来,所以,在BFS过程中还需要记录中间路径,(实际上是构造一棵树),然后在BFS结束之后再进行DFS搜索。这里的一个trick是,在BFS的过程中由后向前找。这样可以避免很多无效的分支。所以需要一个map维护string和它的上一层之间的对应关系。
此外,BFS的搜索过程中并非简单地使用队列的结构,因为每一层与每一层之间要相互隔离,因为很可能上一层之间还有相互指向的支,那么这些支是无效的,应该予以排除。
此外,还要注意什么时候退出循环,当找到end节点之后,并把那一层搜索完之后再退出。
总之这道题很恶心!
代码如下:656ms
分析:这道题首先要找到最短路径,最短路径是采用BFS方法,之前侯大神给我讲的时候说,为什么BFS找到的节点是最短的,因为BFS搜索过程是类似于波浪型的,一层一层荡出去,这样只要找到了结束点,这个店就一定是最短路径。
但是这道题要求把路径找出来,所以,在BFS过程中还需要记录中间路径,(实际上是构造一棵树),然后在BFS结束之后再进行DFS搜索。这里的一个trick是,在BFS的过程中由后向前找。这样可以避免很多无效的分支。所以需要一个map维护string和它的上一层之间的对应关系。
此外,BFS的搜索过程中并非简单地使用队列的结构,因为每一层与每一层之间要相互隔离,因为很可能上一层之间还有相互指向的支,那么这些支是无效的,应该予以排除。
此外,还要注意什么时候退出循环,当找到end节点之后,并把那一层搜索完之后再退出。
总之这道题很恶心!
代码如下:656ms
[code]public class Solution { class Node { String word; int level; public Node(String word, int level) { this.word = word; this.level = level; } } private String end; private List<List<String>> res; private Map<String, List<String>> maps; public List<List<String>> findLadders(String start, String end, Set<String> dict) { res = new ArrayList<>(); // unvisited words set dict.add(end); dict.remove(start); // used to record the map info of <word : the words of next level> maps = new HashMap<>(); for (String e : dict) { maps.put(e, new ArrayList<>()); } // BFS to search from the end to start Queue<Node> queue = new LinkedList<Node>(); queue.add(new Node(start, 0)); boolean found = false; int finalLevel = Integer.MAX_VALUE; int currentLevel = 0; Set<String> visitedWordsInThisLevel = new HashSet<>(); while (!queue.isEmpty()) { Node node = queue.poll(); String word = node.word; int level = node.level; if (level > finalLevel) { break; } if (level > currentLevel) { dict.removeAll(visitedWordsInThisLevel); visitedWordsInThisLevel.clear(); } currentLevel = level; char[] wordCharArray = word.toCharArray(); for (int i = 0; i < word.length(); ++i) { char originalChar = wordCharArray[i]; boolean foundInThisCycle = false; for (char c = 'a'; c <= 'z'; ++c) { wordCharArray[i] = c; String newWord = new String(wordCharArray); if (c != originalChar && dict.contains(newWord)) { maps.get(newWord).add(word); if (newWord.equals(end)) { found = true; finalLevel = currentLevel; foundInThisCycle = true; break; } if (visitedWordsInThisLevel.add(newWord)) { queue.add(new Node(newWord, currentLevel + 1)); } } } if (foundInThisCycle) { break; } wordCharArray[i] = originalChar; } } if(found){ List<String> tmplist = new LinkedList<>(); generatePath(end,start,tmplist); } return res; } private void generatePath(String start,String end,List<String> list){ if(start.equals(end)){ List<String> tmplist = new LinkedList<>(list); tmplist.add(end); Collections.reverse(tmplist); res.add(tmplist); return; } list.add(start); List<String> tmplist = maps.get(start); for(String e:tmplist) generatePath(e,end,list); list.remove(list.size()-1); } }
相关文章推荐
- 算法学习-----插入排序(Java)
- java BigDecimal
- Java Atomic
- java.util.concurrent.atomic原子操作类包
- Java_jdbc 基础笔记之四 数据库连接 (通用更新方法)
- Java中的Atomic包使用指南
- 策略模式
- "javac不是内部或外部命令"的解决办法
- JavaWeb学习总结(二) Servlet
- Java——面向对象概述
- Java_jdbc 基础笔记之三 数据库连接 (Statement)
- 搭建web项目结合spring+cxf的webservice服务
- 实现一颗二叉树,检查二叉树是否平衡(java实现)
- java对像序列化
- Java基础针对自己薄弱环节总结09(线程中)
- java安全沙箱(三)之内置于Java虚拟机(及语言)的安全特性
- jdk1.8 HashMap性能提升
- Java web 学习
- 【java基础】——线程
- 老彭零基础教你学java