leetcode
leetcode 2951 ~ 3000
单词接龙

单词接龙

难度:

标签:

题目描述

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)

代码细节讲解

🦆
在双向广度优先搜索中,为什么选择从两个方向同时进行搜索,而不是仅从一个方向开始?
双向广度优先搜索(Bidirectional BFS)是一种有效的搜索策略,用于从两个方向(起始点和终点)同时进行搜索,以加快搜索速度和提高效率。这种方法的优势在于它可以显著减少需要探索的状态数。单向搜索可能需要遍历大量路径才能到达目标,而双向搜索通过同时从起点和终点向对方进展,使得搜索路径在中间某处相遇,从而减少了搜索路径的长度。一旦两个搜索方向在中间相遇,搜索可以立即停止,这通常会比单向搜索到达终点更快,特别是在状态空间很大时。
🦆
在解法中提到,当发现某个变换后的单词同时出现在两个搜索集合中时,就找到了最短路径。这是如何确保找到的路径是最短的?
在双向广度优先搜索中,两个搜索集合中的每一个都只扩展到当前层级的单词。当某个单词同时出现在两个集合中时,意味着从起点到该单词和从终点到该单词的路径都是最短的,因为广度优先搜索保证了每次扩展都是在当前最短的路径上进行。两个最短路径在某个单词处相遇,因此,这个相遇点代表了从起点到终点的最短路径的连接点。从这个连接点将两边的路径合并,自然形成了整体的最短路径。
🦆
题解中提到的操作`wordDict -= s1`是为了什么目的?这样做有哪些潜在的影响?
操作`wordDict -= s1`的目的是从单词字典中移除已经被当前层处理过的单词。这样做主要是为了防止在后续的搜索中重复考虑这些单词,从而避免创建无效或重复的路径,确保搜索的效率。潜在的影响包括减少了搜索空间,这有助于提高搜索速度,但这也意味着一旦这些单词被移除,它们将不会在任何后续的搜索中被考虑,即使在某些情况下重新考虑它们可能有助于找到其他有效路径。然而,在本题的上下文中,这种影响是积极的,因为我们只关心找到任何有效的最短路径。

相关问题