Skip to content

Commit 0d1ffb0

Browse files
committed
[Function add]
1. Add word ladder questions from leetcode.
1 parent 5b122fa commit 0d1ffb0

File tree

2 files changed

+264
-1
lines changed

2 files changed

+264
-1
lines changed

leetcode/126. Word Ladder II.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
## 126. Word Ladder II
2+
3+
### Question:
4+
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:
5+
* Only one letter can be changed at a time
6+
* Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
7+
8+
Note:
9+
1. Return an empty list if there is no such transformation sequence.
10+
2. All words have the same length.
11+
3. All words contain only lowercase alphabetic characters.
12+
4. You may assume no duplicates in the word list.
13+
5. You may assume beginWord and endWord are non-empty and are not the same.
14+
15+
```
16+
Example 1:
17+
18+
Input:
19+
beginWord = "hit",
20+
endWord = "cog",
21+
wordList = ["hot","dot","dog","lot","log","cog"]
22+
23+
Output:
24+
[
25+
["hit","hot","dot","dog","cog"],
26+
["hit","hot","lot","log","cog"]
27+
]
28+
29+
Example 2:
30+
31+
Input:
32+
beginWord = "hit"
33+
endWord = "cog"
34+
wordList = ["hot","dot","dog","lot","log"]
35+
36+
Output: []
37+
38+
Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.
39+
```
40+
41+
### Solutions
42+
* Method 1: dfs TLE
43+
```Java
44+
class Solution {
45+
private int min = Integer.MAX_VALUE >> 1;
46+
public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
47+
List<List<String>> result = new ArrayList<>();
48+
Set<String> words = new HashSet<>(wordList);
49+
if(!words.contains(endWord)) return result;
50+
int len = beginWord.length();
51+
List<String> temp = new ArrayList<String>();
52+
temp.add(beginWord);
53+
dfs(result, words, len, endWord, beginWord, temp);
54+
return result;
55+
}
56+
private void dfs(List<List<String>> result, Set<String> words, int len, String endWord, String cur, List<String> temp){
57+
if(cur.equals(endWord)){
58+
if(temp.size() < min){
59+
result.clear();
60+
min = temp.size();
61+
}
62+
result.add(new ArrayList<String>(temp));
63+
}else if(temp.size() < min){
64+
for(int i = 0; i < len; i++){
65+
char[] arr = cur.toCharArray();
66+
for(char c = 'a'; c <= 'z'; c++){
67+
arr[i] = c;
68+
String next = new String(arr);
69+
if(words.contains(next)){
70+
words.remove(next);
71+
temp.add(next);
72+
dfs(result, words, len, endWord, next, temp);
73+
temp.remove(temp.size() - 1);
74+
words.add(next);
75+
}
76+
}
77+
arr[i] = cur.charAt(i);
78+
}
79+
}
80+
}
81+
}
82+
```
83+
84+
* Method 2: bfs AC
85+
```Java
86+
class Solution {
87+
private Map<String, List<String>> map;
88+
public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
89+
List<List<String>> result = new LinkedList<>();
90+
Set<String> words = new HashSet<>(wordList);
91+
if(!words.contains(endWord)) return result;
92+
words.remove(beginWord);
93+
LinkedList<String> queue = new LinkedList<>();
94+
map = new HashMap<>();
95+
int len = beginWord.length();
96+
boolean found = false;
97+
queue.add(beginWord);
98+
while(!queue.isEmpty() && !found){
99+
int size = queue.size();
100+
Set<String> curLevel = new HashSet<>();
101+
for(int i = 0; i < size; i++){
102+
String cur = queue.poll();
103+
if(cur.equals(endWord)) found = true;
104+
char[] arr = cur.toCharArray();
105+
for(int l = 0; l < len; l++){
106+
for(char c = 'a'; c <= 'z'; c++){
107+
if(c == cur.charAt(l)) continue;
108+
arr[l] = c;
109+
String next = new String(arr);
110+
if(words.contains(next) || curLevel.contains(next)){
111+
map.put(cur, !map.containsKey(cur) ? new ArrayList<String>(): map.get(cur));
112+
map.get(cur).add(next);
113+
curLevel.add(next);
114+
if(words.contains(next)) queue.offer(next);
115+
words.remove(next);
116+
}
117+
}
118+
arr[l] = cur.charAt(l);
119+
}
120+
}
121+
}
122+
List<String> temp = new LinkedList<>();
123+
temp.add(beginWord);
124+
dfs(result, temp, endWord, beginWord);
125+
return result;
126+
}
127+
private void dfs(List<List<String>> result, List<String> temp, String endWord, String cur){
128+
if(cur.equals(endWord)){
129+
result.add(new ArrayList<>(temp));
130+
}else{
131+
if(!map.containsKey(cur)) return;
132+
List<String> adj = map.get(cur);
133+
for(String s: adj){
134+
temp.add(s);
135+
dfs(result, temp, endWord, s);
136+
temp.remove(temp.size() - 1);
137+
}
138+
}
139+
}
140+
}
141+
```

leetcode/127. Word Ladder.md

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,5 +153,127 @@ class Solution {
153153
}
154154
```
155155

156+
### Third time:
157+
* Method 1: DFS TLE
158+
```JAVA
159+
class Solution {
160+
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
161+
int len = beginWord.length();
162+
int res = dfs(wordList, endWord, beginWord, len, new boolean[wordList.size()]);
163+
return (res == (Integer.MAX_VALUE >> 1)) ? 0 : res;
164+
}
165+
private int dfs(List<String> wordList, String endWord, String cur, int len, boolean[] visited){
166+
if(cur.equals(endWord)) return 1;
167+
else{
168+
int min = Integer.MAX_VALUE >> 1;
169+
for(int i = 0; i < wordList.size(); i++){
170+
if(visited[i] || !isNext(cur, wordList.get(i), len)) continue;
171+
visited[i] = true;
172+
min = Math.min(min, dfs(wordList, endWord, wordList.get(i), len, visited) + 1);
173+
visited[i] = false;
174+
}
175+
return min;
176+
}
177+
}
178+
private boolean isNext(String pre, String next, int len){
179+
int count = 0;
180+
for(int i = 0; i < len; i++){
181+
if(next.charAt(i) == pre.charAt(i)) continue;
182+
else count++;
183+
if(count > 1) return false;
184+
}
185+
return count == 1;
186+
}
187+
}
188+
```
189+
190+
* Method 2: BFS AC
191+
```Java
192+
class Solution {
193+
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
194+
Set<String> remain = new HashSet<>(wordList);
195+
LinkedList<String> queue = new LinkedList<>();
196+
if(!remain.contains(endWord)) return 0;
197+
queue.add(beginWord);
198+
int res = 0, len = beginWord.length();
199+
while(!queue.isEmpty()){
200+
res++;
201+
int size = queue.size();
202+
for(int i = 0; i < size; i++){
203+
String cur = queue.poll();
204+
if(cur.equals(endWord)) return res;
205+
char[] arr = cur.toCharArray();
206+
for(int l = 0; l < len; l++){
207+
char origin = arr[l];
208+
for(char c = 'a'; c <= 'z'; c++){
209+
if(c == origin) continue;
210+
arr[l] = c;
211+
String next = new String(arr);
212+
if(remain.contains(next)){
213+
remain.remove(next);
214+
queue.add(next);
215+
}
216+
}
217+
arr[l] = origin;
218+
}
219+
}
220+
}
221+
return 0;
222+
}
223+
}
224+
```
225+
226+
* Method 3: Bidirectional bfs
227+
```Java
228+
class Solution {
229+
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
230+
Set<String> dict = new HashSet<>(wordList);
231+
if(!dict.contains(endWord)) return 0;
232+
Set<String> head = new HashSet<>();
233+
Set<String> tail = new HashSet<>();
234+
head.add(beginWord);
235+
tail.add(endWord);
236+
int step = 0, len = endWord.length();
237+
while(!head.isEmpty() && !tail.isEmpty()){
238+
++step;
239+
int headSize = head.size(), tailSize = tail.size();
240+
Set<String> temp = null;
241+
if(headSize > tailSize){
242+
temp = head;
243+
head = tail;
244+
tail = temp;
245+
}
246+
Set<String> next = new HashSet<>();
247+
for(String s: head){
248+
char[] arr = s.toCharArray();
249+
for(int i = 0; i < len; i++){
250+
for(char c = 'a'; c <= 'z'; c++){
251+
arr[i] = c;
252+
String newWord = new String(arr);
253+
if(tail.contains(newWord)) return step + 1;
254+
if(dict.contains(newWord)){
255+
next.add(newWord);
256+
dict.remove(newWord);
257+
}
258+
}
259+
arr[i] = s.charAt(i);
260+
}
261+
}
262+
head = next;
263+
}
264+
return 0;
265+
}
266+
}
267+
```
268+
269+
### Conclusion
270+
* How to choose dfs and bfs
271+
1. bfs is designed for shortest path question.
272+
2. At one single stage, we could get the next stage and in every single step, the result is optimized, we can use bfs.
273+
3. dfs can also solve bfs questions while it takes longer time.
274+
4. dfs is used for recording all possible solutions(combination and permutation questions).
275+
156276
### Reference
157-
1. [LeetCode 127. Word Ladder](https://www.jianshu.com/p/753bd585d57e)
277+
1. [LeetCode 127. Word Ladder](https://www.jianshu.com/p/753bd585d57e)
278+
2. [花花酱 LeetCode 127. Word Ladder](http://zxi.mytechroad.com/blog/searching/127-word-ladder/)
279+
3. [什么时候用深搜(dfs)什么时候用广搜(bfs)(转)](https://www.cnblogs.com/Annetree/p/7199358.html)

0 commit comments

Comments
 (0)