LC.P127[单词接龙]
题目描述
字典 wordList
中从单词 beginWord
和 endWord
的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> ... -> sk
:
- 每一对相邻的单词只差一个字母。
- 对于
1 <= i <= k
时,每个 si
都在 wordList
中。注意, beginWord
不需要在 wordList
中。
sk == endWord
给你两个单词 beginWord
和 endWord
和一个字典 wordList
,返回 从 beginWord
到 endWord
的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0
。
示例 1:
输入:beginWord = “hit”, endWord = “cog”, wordList = [“hot”,”dot”,”dog”,”lot”,”log”,”cog”]
输出:5
解释:一个最短转换序列是 “hit” -> “hot” -> “dot” -> “dog” -> “cog”, 返回它的长度 5。
示例 2:
输入:beginWord = “hit”, endWord = “cog”, wordList = [“hot”,”dot”,”dog”,”lot”,”log”]
输出:0
解释:endWord “cog” 不在字典中,所以无法进行转换。
提示:
1 <= beginWord.length <= 10
endWord.length == beginWord.length
1 <= wordList.length <= 5000
wordList[i].length == beginWord.length
beginWord
、endWord
和 wordList[i]
由小写英文字母组成
beginWord != endWord
wordList
中的所有字符串 互不相同
方法一:BFS
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
| class Solution { public int ladderLength(String beginWord, String endWord, List<String> wordList) { if (!wordList.contains(endWord)) return 0; Set<String> visited = new HashSet<>(); Deque<String> queue = new ArrayDeque<>(); visited.add(beginWord); queue.offer(beginWord); int ans = 1; while (!queue.isEmpty()) { int size = queue.size(); ++ans; for (int i = 0; i < size; ++i) { String start = queue.poll(); for (String s : wordList) { if (visited.contains(s)) continue; if (!canConvert(start, s)) continue; if (s.equals(endWord)) return ans; visited.add(s); queue.offer(s); } } } return 0; }
private boolean canConvert(String start, String end) { int cnt = 0; for (int i = 0; i < start.length(); ++i) { if (start.charAt(i) != end.charAt(i)) ++cnt; if (cnt > 1) return false; } return true; } }
|
方法二:BFS(优化visited)
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
| class Solution { public int ladderLength(String beginWord, String endWord, List<String> wordList) { if (!wordList.contains(endWord)) return 0; boolean[] visited = new boolean[wordList.size()]; int index = wordList.indexOf(beginWord); if (index != -1) visited[index] = true; Deque<String> queue = new ArrayDeque<>(); queue.offer(beginWord); int ans = 1; while (!queue.isEmpty()) { int size = queue.size(); ++ans; for (int i = 0; i < size; ++i) { String start = queue.poll(); for (int j = 0; j < wordList.size(); ++j) { if (visited[j]) continue; String s = wordList.get(j); if (!canConvert(start, s)) continue; if (s.equals(endWord)) return ans; visited[j] = true; queue.offer(s); } } } return 0; }
private boolean canConvert(String start, String end) { int cnt = 0; for (int i = 0; i < start.length(); ++i) { if (start.charAt(i) != end.charAt(i)) ++cnt; if (cnt > 1) return false; } return true; } }
|
方法三:双向BFS
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
| class Solution { public int ladderLength(String beginWord, String endWord, List<String> wordList) { int index = wordList.indexOf(endWord); if (index == -1) return 0;
wordList.add(beginWord); Deque<String> queue1 = new ArrayDeque<>(); Deque<String> queue2 = new ArrayDeque<>(); Set<String> visited1 = new HashSet<>(); Set<String> visited2 = new HashSet<>(); queue1.offer(beginWord); queue2.offer(endWord); visited1.add(beginWord); visited2.add(endWord);
int ans = 1; Set<String> wordSet = new HashSet<>(wordList);
while (!queue1.isEmpty() && !queue2.isEmpty()) { ++ans; if (queue1.size() > queue2.size()) { Deque<String> tmp = queue1; queue1 = queue2; queue2 = tmp; Set<String> t = visited1; visited1 = visited2; visited2 = t; } int size1 = queue1.size(); while (size1-- > 0) { String s = queue1.poll(); char[] chars = s.toCharArray(); for (int i = 0; i < s.length(); ++i) { char c0 = chars[i]; for (char c = 'a'; c <= 'z'; ++c) { chars[i] = c; String newString = new String(chars); if (visited1.contains(newString)) continue; if (visited2.contains(newString)) return ans; if (wordSet.contains(newString)) { queue1.offer(newString); visited1.add(newString); } } chars[i] = c0; } } } return 0; } }
|