快轉到主要內容
leetcode 127 - Word Ladder

leetcode 127 - Word Ladder

·
類別 
Leetcode
標籤 
Java Leetcode Hard BFS Problem Blind75
Eason Chiu
作者
Eason Chiu
一個不做筆記就容易忘記的工程師
目錄

題目
#

leetcode 127 - Word Ladder (題目說明請點連結)

題目簡述
#

給定兩個單詞(beginWord 和 endWord)和一個單詞字典 wordList,找出從 beginWord 到 endWord 的最短轉換序列長度。每次只能改變一個字符,且新單詞必須在 wordList 中。

範例
#

Example 1:

Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
Output: 5
Explanation: 一個最短的轉換序列是 "hit" → "hot" → "dot" → "dog" → "cog",長度為 5 個單詞。

Example 2:

Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
Output: 0
Explanation: 終點單詞 "cog" 不在單詞列表中,因此沒有有效的轉換序列。

解題思路
#

這題要求我們找到從 beginWord 到 endWord 的最短轉換序列長度。每次只能改變一個字符,且新單詞必須在 wordList 中。

我們可以用BFS從 beginWord 開始,逐層向外擴展,直到找到 endWord。

解法
#

使用 BFS 來解決:

  1. 首先將 wordList 轉換為 HashSet 以便快速查找。
  2. 檢查 endWord 是否在 wordList 中,如果不在則返回 0。
  3. 使用隊列進行 BFS,從 beginWord 開始。
  4. 對於每個單詞,嘗試改變每個位置的字符(a-z)。
  5. 如果新單詞在 wordList 中,加入隊列並從集合中移除(避免重複訪問)。
  6. 每層代表一個轉換步驟,距離從 1 開始計算。

例子說明
#

beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]

  • 初始情況:queue = ["hit"], distance = 1
  1. 第一層(距離 = 1):

    • 處理 “hit”
    • 嘗試改變每個字符:
      • “ait”, “bit”, …, “zit” → 都不在 wordList 中
      • “hat”, “hbt”, …, “hot” → “hot” 在 wordList 中,加入隊列
      • “hia”, “hib”, …, “hiz” → 都不在 wordList 中
    • 隊列更新為:["hot"]
  2. 第二層(距離 = 2):

    • 處理 “hot”
    • 嘗試改變每個字符:
      • “aot”, “bot”, …, “zot” → 都不在 wordList 中
      • “hat”, “hbt”, …, “hzt” → 都不在 wordList 中
      • “hoa”, “hob”, …, “hoz” → 都不在 wordList 中
    • 隊列更新為:[]
  3. 第三層(距離 = 3):

    • 處理 “dot”
    • 嘗試改變每個字符:
      • “aot”, “bot”, …, “zot” → 都不在 wordList 中
      • “dat”, “dbt”, …, “dzt” → 都不在 wordList 中
      • “doa”, “dob”, …, “dog” → “dog” 在 wordList 中,加入隊列
    • 隊列更新為:["dog"]
  4. 第四層(距離 = 4):

    • 處理 “dog”
    • 嘗試改變每個字符:
      • “aog”, “bog”, …, “cog” → “cog” 在 wordList 中,且是目標單詞
    • 找到目標,返回距離 5

完整程式碼
#

java
import java.util.*;

class Solution {
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {

        // 建立單詞集合以便快速查找
        Set<String> wordSet = new HashSet<>(wordList);

        // 如果終點單詞不在單詞列表中,無法轉換
        if (!wordSet.contains(endWord)) {
            return 0;
        }

        // 使用隊列進行廣度優先搜索
        Queue<String> wordQueue = new LinkedList<>();

        // 從起始單詞開始 BFS
        wordQueue.add(beginWord);

        // 距離從 1 開始(包含起始單詞)
        int distance = 1;

        // BFS 循環:直到隊列為空
        while (!wordQueue.isEmpty()) {
            int size = wordQueue.size(); // 當前層的節點數量

            // 處理當前層級的所有單詞
            for (int i = 0; i < size; i++) {
                String currWord = wordQueue.poll(); // 取出隊首單詞

                // 如果當前單詞是終點單詞,返回距離
                if (currWord.equals(endWord)) {
                    return distance;
                }

                // 嘗試改變當前單詞的每個字符
                for (int j = 0; j < currWord.length(); j++) {
                    char[] temp = currWord.toCharArray(); // 轉換為字符數組

                    // 將位置 j 的字符替換為 a-z 中的每個字母
                    for (char c = 'a'; c <= 'z'; c++) {
                        temp[j] = c;
                        String newWord = new String(temp); // 構建新單詞

                        // 如果新單詞在單詞集合中,加入隊列
                        if (wordSet.contains(newWord)) {
                            wordQueue.add(newWord); // 加入隊列
                            wordSet.remove(newWord); // 移除以避免重複訪問
                        }
                    }
                }
            }

            // 處理完當前層級後增加距離
            distance++;
        }

        // 如果沒有找到轉換序列,返回 0
        return 0;
    }
}

時間複雜度
#

  • 時間複雜度:O(N × L × 26),其中 N 是單詞數量,L 是單詞長度,26 是字符集大小
  • 空間複雜度:O(N),用於存儲隊列和單詞集合

相關文章

leetcode 23 - Merge k Sorted Lists
類別 
Leetcode
標籤 
Java Leetcode Hard Heap Problem Blind75
leetcode 124 - Binary Tree Maximum Path Sum
類別 
Leetcode
標籤 
Java Leetcode Hard DFS Problem Blind75
leetcode 104 - Maximum Depth of Binary Tree
類別 
Leetcode
標籤 
Java Leetcode Easy BFS Problem DFS Problem Tree Problem Blind75