From 20adfa404ccadef190d41bd5c06d2ec559aab5ae Mon Sep 17 00:00:00 2001 From: yuewang0319 Date: Tue, 25 Apr 2017 22:09:22 -0700 Subject: [PATCH] 126 --- #126 | 162 +++++++++++++++++++++++++++-------------------------------- 1 file changed, 74 insertions(+), 88 deletions(-) diff --git a/#126 b/#126 index 87657b3..ee40207 100644 --- a/#126 +++ b/#126 @@ -1,89 +1,75 @@ -126. Word Ladder II - -Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that: - -Only one letter can be changed at a time -Each transformed word must exist in the word list. Note that beginWord is not a transformed word. -For example, - -Given: -beginWord = "hit" -endWord = "cog" -wordList = ["hot","dot","dog","lot","log","cog"] - -Return - [ - ["hit","hot","dot","dog","cog"], - ["hit","hot","lot","log","cog"] - ] - - -public class Solution { - - public List> findLadders(String beginWord, String endWord, List wordList) { - Map map = new HashMap<>(); - Map> neighbors = new HashMap<>(); - neighbors.put(beginWord, new HashSet<>()); - map.put(beginWord, -1); - Set wordSet = new HashSet<>(); - for(String word : wordList){ - wordSet.add(word); - map.put(word, -1); - neighbors.put(word, new HashSet<>()); - } - int distance = 0; - boolean found = false; - Queue queue = new LinkedList<>(); - queue.offer(beginWord); - while(!queue.isEmpty()){ - int len = queue.size(); - for(int i = 0; i < len; i++){ - String curWord = queue.poll(); - if(map.get(curWord) == -1 || map.get(curWord) > distance){ - map.put(curWord, distance); - } - if(curWord.equals(endWord)){ - found = true; - } - for(int j = 0; j < curWord.length(); j++){ - char[] arr = curWord.toCharArray(); - for(char c = 'a'; c <= 'z'; c++){ - if(c != arr[j]){ - arr[j] = c; - } - String newWord = new String(arr); - if(wordSet.contains(newWord)){ - if(map.get(newWord) == -1){ - queue.offer(newWord); - neighbors.get(curWord).add(newWord); - } - } - } - } - } - if(found) break; - distance++; - } - List> wraplist = new ArrayList<>(); - dfs(map, neighbors, new ArrayList<>(), wraplist, beginWord, endWord); - return wraplist; - } - - public void dfs(Map map, Map> neighbors, List sublist, List> wraplist, String curWord, String endWord){ - - if(curWord.equals(endWord)){ - sublist.add(curWord); - wraplist.add(new ArrayList<>(sublist)); - sublist.remove(sublist.size() - 1); - return; - } - - for(String neighbor : neighbors.get(curWord)){ - sublist.add(curWord); - if(map.get(neighbor) == map.get(curWord) + 1){ - dfs(map, neighbors, sublist, wraplist, neighbor, endWord); - } - sublist.remove(sublist.size() - 1); - } - } +public class Solution { + + public List> findLadders(String beginWord, String endWord, List wordList) { + Set wordDict = new HashSet<>(wordList); + Map distances = new HashMap<>(); + Map> graph = new HashMap<>(); + + wordDict.add(beginWord); + for(String word : wordDict){ + graph.put(word, new HashSet<>()); + } + + Queue queue = new LinkedList<>(); + queue.offer(beginWord); + distances.put(beginWord, 0); + boolean found = false; + + while(!queue.isEmpty()){ + String curWord = queue.poll(); + int cur_distance = distances.get(curWord); + Set neighbors = getNeighbors(curWord, wordDict); + for(String neighbor : neighbors){ + graph.get(curWord).add(neighbor); + if(!distances.containsKey(neighbor)){ + distances.put(neighbor, cur_distance + 1); + queue.offer(neighbor); + } + } + if(curWord.equals(endWord)){ + found = true; + break; + } + } + + List> wraplist = new ArrayList<>(); + if(!found) return wraplist; + findPath(distances, graph, new ArrayList<>(), wraplist, endWord, beginWord); + return wraplist; + } + + public Set getNeighbors(String curWord, Set wordSet){ + Set neighbors = new HashSet<>(); + for(int j = 0; j < curWord.length(); j++){ + char[] arr = curWord.toCharArray(); + for(char c = 'a'; c <= 'z'; c++){ + if(c == arr[j]) continue; + arr[j] = c; + String newWord = new String(arr); + if(wordSet.contains(newWord)){ + neighbors.add(newWord); + } + } + } + return neighbors; + } + + public void findPath(Map distances, Map> graph, List sublist, List> wraplist, String curWord, String startWord){ + + sublist.add(curWord); + if(curWord.equals(startWord)){ + List res = new ArrayList<>(sublist); + Collections.reverse(res); + wraplist.add(res); + sublist.remove(sublist.size() - 1); + return; + } + + for(String neighbor : graph.get(curWord)){ + if(distances.get(neighbor) == distances.get(curWord) - 1){ + findPath(distances, graph, sublist, wraplist, neighbor, startWord); + } + } + sublist.remove(sublist.size() - 1); + } } \ No newline at end of file