Skip to content

Commit e806719

Browse files
committed
word ladder2
1 parent 3cb8e16 commit e806719

File tree

3 files changed

+183
-0
lines changed

3 files changed

+183
-0
lines changed

src/main/java/joshua/leetcode/array/ProductOfArrayExceptSelf.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,38 @@ public int[] productExceptSelf(int[] nums) {
5959
return fromLeft;
6060
}
6161
}
62+
63+
/**
64+
* 方法2是方法1的一种巧妙的改进。
65+
* 注意到方法1的两个list,fromLeft和fromRight可以合并。
66+
* 在计算完fromLeft之后,实际上可以直接从fromLeft的尾部开始往左扫描,在计算result[k]的时候,
67+
* fromLeft[0]用来存储nums[k+1,..,len-1]的乘积,在之前的计算中result[k]存储的是nums[0,...,k-1]的乘积,两者相乘就得到了最终结果。
68+
* 同时可以将fromLeft[0]更新为fromLeft[0]*nums[k]
69+
*/
70+
public static class Solution2 extends ProductOfArrayExceptSelf {
71+
72+
@Override
73+
public int[] productExceptSelf(int[] nums) {
74+
// i.e. [1,2,3,4]
75+
int[] result = new int[nums.length];
76+
for (int i = 0; i < nums.length; i++) {
77+
if(i == 0) {
78+
result[0] = 1;
79+
} else {
80+
result[i] = result[i-1] * nums[i-1];
81+
}
82+
}
83+
/* result is now: [1, 1, 2, 6]
84+
* the next iteration will be:
85+
* [1,1,2,6] -> [1,1,2,6] -> [4,1,2,6]
86+
* [4,1,2,6] -> [4,1,8,6] -> [12,1,8,6]
87+
* [12,1,8,6] -> [12,12,8,6] -> [24,12,8,6]
88+
*/
89+
for(int i = nums.length - 1; i > 0; i--) {
90+
result[i] = result[i] * result[0];
91+
result[0] *= nums[i];
92+
}
93+
return result;
94+
}
95+
}
6296
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// Copyright 2016 Baidu Inc. All rights reserved.
2+
3+
package joshua.leetcode.bfs;
4+
5+
import java.util.ArrayList;
6+
import java.util.LinkedList;
7+
import java.util.List;
8+
import java.util.Set;
9+
10+
/**
11+
* 126. Word Ladder II</br>
12+
* <p/>
13+
* <a href="https://leetcode.com/problems/word-ladder-ii/">leetcode link</a>
14+
*
15+
* @author Jiang Yong ([email protected])
16+
*/
17+
public abstract class WordLadder2 {
18+
19+
/**
20+
* Given two words (beginWord and endWord), and a dictionary's word list,
21+
* find all shortest transformation sequence(s) from beginWord to endWord, such that:
22+
* <p/>
23+
* Only one letter can be changed at a time
24+
* Each intermediate word must exist in the word list
25+
* For example,
26+
* <p/>
27+
* Given:<br/>
28+
* beginWord = "hit"
29+
* endWord = "cog"
30+
* wordList = ["hot","dot","dog","lot","log"]
31+
* Return
32+
* [
33+
* ["hit","hot","dot","dog","cog"],
34+
* ["hit","hot","lot","log","cog"]
35+
* ]
36+
* <br/>
37+
* Note:<br/>
38+
* <ul>
39+
* <li>All words have the same length.</li>
40+
* <li>All words contain only lowercase alphabetic characters./li>
41+
* </ul>
42+
*
43+
* @param beginWord
44+
* @param endWord
45+
* @param wordList
46+
* @return
47+
*/
48+
public abstract List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList);
49+
50+
/**
51+
*
52+
*/
53+
public static class Solution1 extends WordLadder2 {
54+
55+
/**
56+
* BFS算法,但是需要对每个节点保存已走过的路径。
57+
*
58+
* @param beginWord
59+
* @param endWord
60+
* @param wordList
61+
* @return
62+
*/
63+
@Override
64+
public List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) {
65+
List<QueueItem> steps = new LinkedList<QueueItem>();
66+
List<String> path = new ArrayList<String>();
67+
path.add(beginWord);
68+
steps.add(new QueueItem(beginWord, path));
69+
List<List<String>> result = new ArrayList<List<String>>();
70+
boolean found = false;
71+
while (!steps.isEmpty()) {
72+
List<QueueItem> newSteps = new LinkedList<QueueItem>();
73+
for (int i = 0; i < steps.size(); i++) {
74+
QueueItem oldStep = steps.get(i);
75+
char[] chars = oldStep.word.toCharArray();
76+
boolean reached = false;
77+
for (int j = 0; j < chars.length; j++) {
78+
char ch = chars[j];
79+
for (int k = 0; k < 26; k++) {
80+
chars[j] = (char) (k + 'a');
81+
if (ch != chars[j]) {
82+
String str = new String(chars);
83+
if (str.equals(endWord)) {
84+
found = reached = true;
85+
oldStep.path.add(endWord);
86+
result.add(oldStep.path);
87+
break;
88+
}
89+
if (wordList.contains(str)) {
90+
List<String> newPath = new ArrayList<String>(oldStep.path);
91+
newPath.add(str);
92+
newSteps.add(new QueueItem(str, newPath));
93+
}
94+
}
95+
}
96+
if (reached) {
97+
break;
98+
} else {
99+
chars[j] = ch;
100+
}
101+
}
102+
}
103+
if (found) {
104+
break;
105+
} else {
106+
for (QueueItem item : newSteps) {
107+
wordList.remove(item.word);
108+
}
109+
steps = newSteps;
110+
}
111+
}
112+
return result;
113+
}
114+
115+
class QueueItem {
116+
String word;
117+
List<String> path;
118+
119+
public QueueItem(String word, List<String> path) {
120+
this.word = word;
121+
this.path = path;
122+
}
123+
}
124+
}
125+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package joshua.leetcode.bfs;
2+
3+
import static org.junit.Assert.*;
4+
5+
import java.util.List;
6+
import java.util.Set;
7+
8+
import org.junit.Test;
9+
10+
import com.google.common.collect.Sets;
11+
12+
public class WordLadder2Test {
13+
14+
@Test
15+
public void testSolution() {
16+
String beginWord = "hit";
17+
String endWord = "cog" ;
18+
Set<String> wordList = Sets.newHashSet("hot","dot","dog","lot","log");
19+
WordLadder2 solution = new WordLadder2.Solution1();
20+
List<List<String>> result = solution.findLadders(beginWord, endWord, wordList);
21+
System.out.println(result);
22+
}
23+
24+
}

0 commit comments

Comments
 (0)