[Leetcode] 126 Word Ladder II 解题 (和127的对比)

Loading...icon-default.png?t=M4ADhttps://leetcode.com/problems/word-ladder-ii/

这道题区别于127 Word Ladder 在于

1. 127 求的是最短路径长度;本题求的是最短路径

2. 127 求的是一个值,本题求的是所有的最短路径

为了解决这个变化,关键点是

1. 对于上一层之前访问的节点我们不能再访问了

2. 对于下一层要访问的节点,我们要记录所有的路径。

class Solution:
    def findLadders(self, beginWord: str, endWord: str, wordList: List[str]) -> List[List[str]]:
        
        if endWord not in wordList:
            return []
        
        word_dict = set(wordList)
        queue = collections.deque([beginWord])
        # dict[word(str), paths(List[List[str]]): all paths from beginWord to endWord]
        seen = {beginWord: [  [ beginWord ] ] }

        while queue:
            
            seen_in_this_level = {} 
            for _ in range(len(queue)):
                word = queue.popleft()
                
                if word == endWord:
                    return seen[word]
                
                for next_word in self._get_next_words(word, word_dict):
                    if next_word in seen:
                        continue
                    
                    # !! instead of adding next_word into 'seen'
                    # we add it into 'seen_in_this_level'
                    # because multiple words may have 'endWord' as the next word
                    #
                    #     ted    rex   <-- current level
                    #      \     /
                    #        tex       <-- next_word
                    #
                    #  when word 'tex', next_word = 'tax', if we put 'tax' into 'seen',
                    #  later when we visit word 'rex', we will skip 'tax', missing this valid path
                    if next_word not in seen_in_this_level:
                        seen_in_this_level[next_word] = []
                    paths = seen[word]
                    for path in paths:
                        new_path = path.copy()
                        new_path.append(next_word)
                        seen_in_this_level[next_word].append(new_path)
                    
            # !! de-dupe because we may see 'endWord' multiple times 
            queue = collections.deque(seen_in_this_level) 
            # !! add 'seen_in_this_level' to 'seen' only when the level is finished
            seen.update(seen_in_this_level)
        
        return []
                
    def _get_next_words(self, word: str, word_dict: set[str]) -> set[str]:
        next_words = set()
        for i in range(len(word)):
            ch = word[i]
            left_substr, right_substr = word[: i], word[i + 1:]
            for letter in "abcdefghijklmnopqrstuvwxyz":
                new_word = left_substr + letter + right_substr
                if new_word != word and new_word in word_dict:
                    next_words.add(new_word)
        return next_words

和 126的解题对比

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值