|
1 | 1 | package com.fishercoder.solutions;
|
2 | 2 |
|
3 |
| -import java.util.ArrayList; |
4 |
| -import java.util.List; |
| 3 | +import java.util.*; |
5 | 4 |
|
6 | 5 | /**
|
7 | 6 | * 126. Word Ladder II
|
|
32 | 31 | You may assume beginWord and endWord are non-empty and are not the same.
|
33 | 32 | */
|
34 | 33 | public class _126 {
|
| 34 | + /**Reference: https://discuss.leetcode.com/topic/2857/share-two-similar-java-solution-that-accpted-by-oj*/ |
35 | 35 |
|
36 |
| - public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) { |
37 |
| - List<List<String>> result = new ArrayList<>(); |
38 |
| - return result; |
| 36 | + Map<String, List<String>> map; |
| 37 | + List<List<String>> results; |
| 38 | + |
| 39 | + public List<List<String>> findLadders(String start, String end, List<String> dict) { |
| 40 | + results = new ArrayList<>(); |
| 41 | + if (dict.size() == 0) |
| 42 | + return results; |
| 43 | + |
| 44 | + int min = Integer.MAX_VALUE; |
| 45 | + |
| 46 | + Queue<String> queue = new ArrayDeque<>(); |
| 47 | + queue.add(start); |
| 48 | + |
| 49 | + map = new HashMap<>(); |
| 50 | + |
| 51 | + Map<String, Integer> ladder = new HashMap<>(); |
| 52 | + for (String string : dict) |
| 53 | + ladder.put(string, Integer.MAX_VALUE); |
| 54 | + ladder.put(start, 0); |
| 55 | + |
| 56 | + dict.add(end); |
| 57 | + //BFS: Dijisktra search |
| 58 | + while (!queue.isEmpty()) { |
| 59 | + |
| 60 | + String word = queue.poll(); |
| 61 | + |
| 62 | + int step = ladder.get(word) + 1;//'step' indicates how many steps are needed to travel to one word. |
| 63 | + |
| 64 | + if (step > min) break; |
| 65 | + |
| 66 | + for (int i = 0; i < word.length(); i++) { |
| 67 | + StringBuilder builder = new StringBuilder(word); |
| 68 | + for (char ch = 'a'; ch <= 'z'; ch++) { |
| 69 | + builder.setCharAt(i, ch); |
| 70 | + String new_word = builder.toString(); |
| 71 | + if (ladder.containsKey(new_word)) { |
| 72 | + |
| 73 | + if (step > ladder.get(new_word)) {//Check if it is the shortest path to one word. |
| 74 | + continue; |
| 75 | + } else if (step < ladder.get(new_word)) { |
| 76 | + queue.add(new_word); |
| 77 | + ladder.put(new_word, step); |
| 78 | + } else ;// It is a KEY line. If one word already appeared in one ladder, |
| 79 | + // Do not insert the same word inside the queue twice. Otherwise it gets TLE. |
| 80 | + |
| 81 | + if (map.containsKey(new_word)) {//Build adjacent Graph |
| 82 | + map.get(new_word).add(word); |
| 83 | + } else { |
| 84 | + List<String> list = new LinkedList<String>(); |
| 85 | + list.add(word); |
| 86 | + map.put(new_word, list); |
| 87 | + //It is possible to write three lines in one: |
| 88 | + //map.put(new_word,new LinkedList<String>(Arrays.asList(new String[]{word}))); |
| 89 | + //Which one is better? |
| 90 | + } |
| 91 | + |
| 92 | + if (new_word.equals(end)) { |
| 93 | + min = step; |
| 94 | + } |
| 95 | + |
| 96 | + }//End if dict contains new_word |
| 97 | + }//End:Iteration from 'a' to 'z' |
| 98 | + }//End:Iteration from the first to the last |
| 99 | + }//End While |
| 100 | + |
| 101 | + //BackTracking |
| 102 | + LinkedList<String> result = new LinkedList<>(); |
| 103 | + backTrace(end, start, result); |
| 104 | + |
| 105 | + return results; |
| 106 | + } |
| 107 | + |
| 108 | + private void backTrace(String word, String start, List<String> list) { |
| 109 | + if (word.equals(start)) { |
| 110 | + list.add(0, start); |
| 111 | + results.add(new ArrayList<>(list)); |
| 112 | + list.remove(0); |
| 113 | + return; |
| 114 | + } |
| 115 | + list.add(0, word); |
| 116 | + if (map.get(word) != null) { |
| 117 | + for (String s : map.get(word)) { |
| 118 | + backTrace(s, start, list); |
| 119 | + } |
| 120 | + } |
| 121 | + list.remove(0); |
39 | 122 | }
|
40 | 123 |
|
41 | 124 | }
|
0 commit comments