leetcode - 126. Word Ladder II

Description

A transformation sequence from word beginWord to word endWord using a dictionary wordList is a sequence of words beginWord -> s1 -> s2 -> ... -> sk such that:

Every adjacent pair of words differs by a single letter.

Every si for 1 <= i <= k is in wordList. Note that beginWord does not need to be in wordList.

sk == endWord

Given two words, beginWord and endWord, and a dictionary wordList, return all the shortest transformation sequences from beginWord to endWord, or an empty list if no such sequence exists. Each sequence should be returned as a list of the words [beginWord, s1, s2, ..., sk].

Example 1:

复制代码
Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
Output: [["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]]
Explanation: There are 2 shortest transformation sequences:
"hit" -> "hot" -> "dot" -> "dog" -> "cog"
"hit" -> "hot" -> "lot" -> "log" -> "cog"

Example 2:

复制代码
Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
Output: []
Explanation: The endWord "cog" is not in wordList, therefore there is no valid transformation sequence.

Constraints:

复制代码
1 <= beginWord.length <= 5
endWord.length == beginWord.length
1 <= wordList.length <= 500
wordList[i].length == beginWord.length
beginWord, endWord, and wordList[i] consist of lowercase English letters.
beginWord != endWord
All the words in wordList are unique.
The sum of all shortest transformation sequences does not exceed 10^5.

Solution

TLE: bfs + backtracing. Similar to 127. Word Ladder, this time we will need to print out the paths. So I will call 127's function first, to get the shortest path length, and then use dfs/back tracking to find the paths that has this length.

Code

python3 复制代码
class Solution:
    def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
        word_list = set(wordList)
        if endWord not in word_list:
            return 0
        queue = collections.deque([(endWord, 1)])
        visited = set()
        while queue:
            cur_word, step = queue.popleft()
            if cur_word in visited:
                continue
            visited.add(cur_word)
            if cur_word == beginWord:
                return step
            for i in range(len(cur_word)):
                for dz in range(26):
                    new_char = chr(ord('a') + dz)
                    if new_char == cur_word[i]:
                        continue
                    new_word = f'{cur_word[:i]}{new_char}{cur_word[i+1:]}'
                    if new_word in word_list or new_word == beginWord:
                        queue.append((new_word, step + 1))
        return 0
    def findLadders(self, beginWord: str, endWord: str, wordList: List[str]) -> List[List[str]]:
        ladder_length = self.ladderLength(beginWord, endWord, wordList)
        if ladder_length == 0:
            return []
        res = []
        word_list = set(wordList)
        candidates = {}
        for each_word in word_list | set([beginWord]):
            candidates[each_word] = []
            for i in range(len(each_word)):
                for dz in range(26):
                    new_char = chr(ord('a') + dz)
                    if new_char == each_word[i]:
                        continue
                    new_word = f'{each_word[:i]}{new_char}{each_word[i+1:]}'
                    if new_word in word_list:
                        candidates[each_word].append(new_word)
        def dfs(cur_word: str, cur_res: list) -> None:
            if cur_word == endWord and len(cur_res) == ladder_length:
                res.append(cur_res)
            elif len(cur_res) > ladder_length:
                return
            else:
                for candidate_word in candidates[cur_word]:
                    dfs(candidate_word, cur_res + [candidate_word])
        dfs(beginWord, [beginWord])
        return res
相关推荐
a177988771214 分钟前
小程序码的生成与获取码中的scene
小程序·c#
无风听海31 分钟前
.NET10之C# Target-typed new expression深入解析
windows·c#·.net
老四啊laosi35 分钟前
[双指针] 5. 有效三角形的个数
算法·leetcode·有效三角形的个数
这辈子谁会真的心疼你1 小时前
怎么修改pdf文档属性?介绍三个方法
数据库·pdf·c#
1104.北光c°1 小时前
Leetcode146 LRU缓存的三种写法 【hot100算法个人笔记】【java写法】
java·开发语言·笔记·算法·leetcode·hot100·lru缓存
6Hzlia1 小时前
【Hot 100 刷题计划】 LeetCode 239. 滑动窗口最大值 | C++ 优先队列与单调队列双解法
数据结构·算法·leetcode
迷海1 小时前
力扣原题《打家劫舍》递归版动态规划,纯手搓,已验证,未优化
c++·leetcode·动态规划
6Hzlia12 小时前
【Hot 100 刷题计划】 LeetCode 118. 杨辉三角 | C++ 动态规划题解
c++·leetcode·动态规划
逆境不可逃14 小时前
LeetCode 热题 100 之 543. 二叉树的直径 102. 二叉树的层序遍历 108. 将有序数组转换为二叉搜索树 98. 验证二叉搜索树
算法·leetcode·职场和发展
副露のmagic14 小时前
哈希章节 leetcode 思路&实现
算法·leetcode·哈希算法