单词接龙
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 61 ms, 内存: 16.8 MB
/*
题目思路:
1. 使用广度优先搜索(BFS)找到从beginWord到endWord的最短转换序列。
2. 使用Java Stream来处理单词集合的操作。
3. 每次转换只能改变一个字母,且中间单词必须在wordList中。
4. 使用队列进行BFS,每次从队列中取出一个单词,尝试改变其每个位置的字符,如果生成的新单词在wordList中且未被访问过,则将新单词加入队列。
5. 重复上述过程直到找到endWord或队列为空。
*/
import java.util.*;
import java.util.stream.*;
public class Solution {
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
Set<String> wordSet = wordList.stream().collect(Collectors.toSet());
if (!wordSet.contains(endWord)) return 0;
Queue<String> queue = new LinkedList<>();
queue.add(beginWord);
Set<String> visited = new HashSet<>();
visited.add(beginWord);
int length = 1;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
String word = queue.poll();
char[] chars = word.toCharArray();
for (int j = 0; j < chars.length; j++) {
char originalChar = chars[j];
for (char c = 'a'; c <= 'z'; c++) {
if (c == originalChar) continue;
chars[j] = c;
String newWord = new String(chars);
if (newWord.equals(endWord)) return length + 1;
if (wordSet.contains(newWord) && !visited.contains(newWord)) {
queue.add(newWord);
visited.add(newWord);
}
}
chars[j] = originalChar;
}
}
length++;
}
return 0;
}
}
解释
方法:
这道题可以使用双向广度优先搜索(Bidirectional BFS)来解决。思路是从起始单词和结束单词同时开始搜索,每次都扩展当前层的单词,直到两边相遇。这样可以大大减少搜索的范围,从而提高效率。在搜索过程中,每次都尝试改变当前单词的每个字母,看是否能得到字典中的单词,如果能,则加入下一层的搜索队列中。当发现某个变换后的单词同时出现在从起始单词和结束单词扩展的集合中时,说明找到了最短路径。
时间复杂度:
O(N*L)
空间复杂度:
O(N)
代码细节讲解
🦆
在双向广度优先搜索中,为什么选择从两个方向同时进行搜索,而不是仅从一个方向开始?
▷🦆
在解法中提到,当发现某个变换后的单词同时出现在两个搜索集合中时,就找到了最短路径。这是如何确保找到的路径是最短的?
▷🦆
题解中提到的操作`wordDict -= s1`是为了什么目的?这样做有哪些潜在的影响?
▷