- Only one letter can be changed at a time
- Each intermediate word must exist in the dictionary
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.
// Algorithm is correct but exceeds time limit. public class Solution { private List<List<String>> result; private List<String> reversedPath; private Map<String, List<String>> map; private int shortLen; public List<List<String>> findLadders(String start, String end, Set<String> dict) { // Adopt breath first search result = new LinkedList<>(); reversedPath = new LinkedList<>(); map = new HashMap<>(); shortLen = Integer.MAX_VALUE; bfs(start, end, dict); if (shortLen == Integer.MAX_VALUE) return result; reversedPath.add(end); backTracking(end, 1); return result; } private void backTracking(String end, int cnt) { if (cnt == shortLen) { List<String> path = new LinkedList<>(); for (int i = reversedPath.size()-1; i >= 0; i--) path.add(reversedPath.get(i)); if (!result.contains(path)) result.add(path); } else { for (String str : map.get(end)) { reversedPath.add(str); backTracking(str, cnt+1); reversedPath.remove(reversedPath.size()-1); } } } private void bfs(String start, String end, Set<String> dict) { Queue<String> word = new LinkedList<>(); Queue<Integer> length = new LinkedList<>(); word.offer(start); length.offer(2); while (!word.isEmpty()) { String v = word.poll(); int len = length.poll(); if (len > shortLen) return; for (int i = 0; i < v.length(); i++) { // Note: Adopt character replacement strategy can save much time. for (char c = 'a'; c <= 'z'; c++) { if (v.charAt(i) == c) continue; String w = replace(v, i, c); if (map.containsKey(v) && map.get(v).contains(w)) continue; if (w.equals(end)) { shortLen = len; if (!map.containsKey(end)) { List<String> parent = new LinkedList<>(); parent.add(v); map.put(end, parent); } else map.get(end).add(v); } if (dict.contains(w)) { if (!map.containsKey(w)) { List<String> parent = new LinkedList<>(); parent.add(v); map.put(w, parent); } else map.get(w).add(v); word.offer(w); length.offer(len+1); } } } } } private String replace(String s, int index, char c) { char[] chars = s.toCharArray(); chars[index] = c; return new String(chars); } }
No comments:
Post a Comment