forked from fishercoder1534/Leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
_126.java
144 lines (119 loc) · 4.86 KB
/
_126.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package com.fishercoder.solutions;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
/**
* 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"]
]
Note:
Return an empty list if there is no such transformation sequence.
All words have the same length.
All words contain only lowercase alphabetic characters.
You may assume no duplicates in the word list.
You may assume beginWord and endWord are non-empty and are not the same.
*/
public class _126 {
public static class Solution1 {
/** Reference: https://discuss.leetcode.com/topic/2857/share-two-similar-java-solution-that-accpted-by-oj */
Map<String, List<String>> map;
List<List<String>> results;
public List<List<String>> findLadders(String start, String end, List<String> dict) {
results = new ArrayList<>();
if (dict.size() == 0) {
return results;
}
int min = Integer.MAX_VALUE;
Queue<String> queue = new ArrayDeque<>();
queue.add(start);
map = new HashMap<>();
Map<String, Integer> ladder = new HashMap<>();
for (String string : dict) {
ladder.put(string, Integer.MAX_VALUE);
}
ladder.put(start, 0);
dict.add(end);
//BFS: Dijisktra search
while (!queue.isEmpty()) {
String word = queue.poll();
int step = ladder.get(word)
+ 1;//'step' indicates how many steps are needed to travel to one word.
if (step > min) {
break;
}
for (int i = 0; i < word.length(); i++) {
StringBuilder builder = new StringBuilder(word);
for (char ch = 'a'; ch <= 'z'; ch++) {
builder.setCharAt(i, ch);
String newWord = builder.toString();
if (ladder.containsKey(newWord)) {
if (step > ladder.get(newWord)) {
//Check if it is the shortest path to one word.
continue;
} else if (step < ladder.get(newWord)) {
queue.add(newWord);
ladder.put(newWord, step);
} else {
// It is a KEY line. If one word already appeared in one ladder,
// Do not insert the same word inside the queue twice. Otherwise it gets TLE.
}
if (map.containsKey(newWord)) {
//Build adjacent Graph
map.get(newWord).add(word);
} else {
List<String> list = new LinkedList();
list.add(word);
map.put(newWord, list);
//It is possible to write three lines in one:
//map.put(new_word,new LinkedList<String>(Arrays.asList(new String[]{word})));
//Which one is better?
}
if (newWord.equals(end)) {
min = step;
}
}
//End if dict contains new_word
}
//End:Iteration from 'a' to 'z'
}
//End:Iteration from the first to the last
}
//End While
//BackTracking
LinkedList<String> result = new LinkedList<>();
backTrace(end, start, result);
return results;
}
private void backTrace(String word, String start, List<String> list) {
if (word.equals(start)) {
list.add(0, start);
results.add(new ArrayList<>(list));
list.remove(0);
return;
}
list.add(0, word);
if (map.get(word) != null) {
for (String s : map.get(word)) {
backTrace(s, start, list);
}
}
list.remove(0);
}
}
}