|
33 | 33 |
|
34 | 34 | public class _127 {
|
35 | 35 |
|
36 |
| - /**reference: https://discuss.leetcode.com/topic/29303/two-end-bfs-in-java-31ms/16*/ |
| 36 | + /**this one https://discuss.leetcode.com/topic/29303/two-end-bfs-in-java-31ms fails by test case _127Test.test1(). |
| 37 | + * All transformed words, including endWord must be in wordList. |
| 38 | + * |
| 39 | + * And we can share a visited set from both ends since we cannot remove word from dict.*/ |
37 | 40 | public int ladderLength(String beginWord, String endWord, List<String> wordList) {
|
38 |
| - Set<String> dict = new HashSet<>(wordList); |
39 |
| - Set<String> startSet = new HashSet<>(); |
| 41 | + Set<String> beginSet = new HashSet<>(); |
40 | 42 | Set<String> endSet = new HashSet<>();
|
41 | 43 | Set<String> visited = new HashSet<>();
|
| 44 | + Set<String> dict = new HashSet<>(wordList); |
| 45 | + int len = 1; |
| 46 | + |
| 47 | + beginSet.add(beginWord); |
42 | 48 |
|
43 |
| - startSet.add(beginWord); |
44 | 49 | if (dict.contains(endWord)) {
|
45 |
| - endSet.add(endWord); // all transformed words must be in dict (including endWord) |
| 50 | + endSet.add(endWord); |
46 | 51 | }
|
47 | 52 |
|
48 |
| - for (int len = 2; !startSet.isEmpty(); len++) { |
49 |
| - Set<String> nq = new HashSet<>(); |
50 |
| - for (String w : startSet) { |
51 |
| - for (int j = 0; j < w.length(); j++) { |
52 |
| - char[] ch = w.toCharArray(); |
| 53 | + while (!beginSet.isEmpty() && !endSet.isEmpty()) { |
| 54 | + if (beginSet.size() > endSet.size()) { |
| 55 | + Set<String> temp = beginSet; |
| 56 | + beginSet = endSet; |
| 57 | + endSet = temp; |
| 58 | + } |
| 59 | + |
| 60 | + Set<String> temp = new HashSet<>(); |
| 61 | + for (String word : beginSet) { |
| 62 | + char[] chars = word.toCharArray(); |
| 63 | + for (int i = 0; i < chars.length; i++) { |
53 | 64 | for (char c = 'a'; c <= 'z'; c++) {
|
54 |
| - if (c == w.charAt(j)) continue; // beginWord and endWord should not be the same |
55 |
| - ch[j] = c; |
56 |
| - String nb = String.valueOf(ch); |
57 |
| - if (endSet.contains(nb)) { |
58 |
| - return len; // meet from two ends |
| 65 | + char old = chars[i]; |
| 66 | + chars[i] = c; |
| 67 | + String newWord = new String(chars); |
| 68 | + if (endSet.contains(newWord)) { |
| 69 | + return len + 1; |
59 | 70 | }
|
60 |
| - if (dict.contains(nb) && visited.add(nb)) { |
61 |
| - nq.add(nb); // not meet yet, visited is safe to use |
| 71 | + |
| 72 | + if (!visited.contains(newWord) && dict.contains(newWord)) { |
| 73 | + visited.add(newWord); |
| 74 | + temp.add(newWord); |
62 | 75 | }
|
| 76 | + chars[i] = old; |
63 | 77 | }
|
64 | 78 | }
|
65 | 79 | }
|
66 | 80 |
|
67 |
| - startSet = (nq.size() < endSet.size()) ? nq : endSet; // switch to small one to traverse from other end |
68 |
| - endSet = (startSet == nq) ? endSet : nq; |
| 81 | + beginSet = temp; |
| 82 | + len++; |
69 | 83 | }
|
70 | 84 | return 0;
|
71 | 85 | }
|
|
0 commit comments