|
Word Ladder II Total Accepted: 11755 Total Submissions: 102776My Submissions
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. 这个题目着实用了不少时间,中间做了两个取巧的处理:
1.把end放到dict里面这样的好处就是在BFS建立图的时候 可以直接获取end的前继,所有.这样可以减少最后处理的麻烦 2.把dfs中处理进行优化,可以直接处理到当前继没有的时候,这个时候最后一个节点一定是start 3.中间建立一个MAP map中保存不同的str对应的前继 4.如果一个串被发现了,那么要看一下是不是distance和之前的str差一个,这个是为了保证不出现绕环 5.对str的每一位做变换,使时间复杂度下来.而刚开始的时候是比较有一个位不相同,但是对海量的处理的时候反而会降低速度. 6.对最后结果要把新的放在0位,oneAnswer.add(0,end).因为是从后往前扫 public class Solution {
public ArrayList
> findLadders(String start,
String end, HashSet
dict) { dict.add(end); ArrayList
> result = new ArrayList
>(); if (start == null || end == null || start.length() != end.length()) { return result; } Map
map = new HashMap
(); Queue
queue = new LinkedList
(); queue.offer(start); map.put(start, new MyNode(start, 1)); while (!queue.isEmpty()) { String cur = queue.poll(); if (reachEnd(cur, end)) { outputResult(end, new ArrayList
(), map, result); return result; } for (int i = 0; i < cur.length(); i++) { for (char c = 'a'; c <= 'z'; c++) { String changeStr = getOneDiff(cur, i, c); if (dict.contains(changeStr)) { MyNode curNode = map.get(cur); int curDist = curNode.distance; int newDist = curDist + 1; if (!map.containsKey(changeStr)) { MyNode newNode = new MyNode(changeStr, newDist); newNode.pre.add(curNode); queue.offer(changeStr); map.put(changeStr, newNode); } else { MyNode preNode = map.get(changeStr); int preDist = preNode.distance; if (newDist == preDist) { preNode.pre.add(curNode); } } } } } } return result; } private void outputResult(String end, ArrayList
oneAnswer, Map
map, ArrayList
> result) { MyNode curNode = map.get(end); oneAnswer.add(0, end); if (curNode.pre.isEmpty()) { result.add(new ArrayList
(oneAnswer)); return; } for (MyNode eachNode : curNode.pre) { outputResult(eachNode.val, oneAnswer, map, result); oneAnswer.remove(0); } } private void getPaths(MyNode myNode, Map
map, ArrayList
curPath, ArrayList
> paths) { if (myNode == null) { paths.add(curPath); return; } curPath.add(0, myNode.val); if (!myNode.pre.isEmpty()) { for (MyNode prevNode : myNode.pre) { getPaths(prevNode, map, new ArrayList
(curPath), paths); } } else { getPaths(null, map, curPath, paths); } } boolean reachEnd(String left, String right) { if (left.equals(right)) { return true; } return false; } String getOneDiff(String str, int pos, char c) { StringBuffer sb = new StringBuffer(str); sb.setCharAt(pos, c); return sb.toString(); } } class MyNode { String val; int distance; LinkedList
pre; MyNode(String v, int distance) { this.val = v; this.distance = distance; pre = new LinkedList
(); } void addPre(MyNode p) { pre.add(p); } }
不得不说,这个题做的确实痛苦,但是做AC了之后感觉很爽! 也不知道各位大神有什么更好的办法,反正我做的时候确实感觉到很挑战,但很有意思. 过瘾!
|