Leetcode 126.单词接龙 II(Word Ladder II)

Leetcode 126.单词接龙 II

1 题目描述(Leetcode题目链接

  给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列。转换需遵循如下规则:

  • 每次转换只能改变一个字母。
  • 转换过程中的中间单词必须是字典中的单词。

说明:

  • 如果不存在这样的转换序列,返回一个空列表。
  • 所有单词具有相同的长度。
  • 所有单词只由小写字母组成。
  • 字典中不存在重复的单词。
  • 你可以假设 beginWord 和 endWord 是非空的,且二者不相同。
输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

输出:
[
  ["hit","hot","dot","dog","cog"],
  ["hit","hot","lot","log","cog"]
]
输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

输出: []

解释: endWord "cog" 不在字典中,所以不存在符合要求的转换序列。

2 题目链接

  这个题目不难,但是很麻烦。思路也很直观,就是先广度优先搜索,构造出前驱子图,到最后对前驱子图进行深度优先搜索输出路径序列。更多有关图的内容

class Solution:
    def dfs(self, root, path):
        if self.parent[root]:
            for word in self.parent[root]:
                self.dfs(word, path + [word])
        else:
            self.res.append(path[::-1])

    def findLadders(self, beginWord: str, endWord: str, wordList: List[str]) -> List[List[str]]:
        self.res = []
        self.parent = collections.defaultdict(set)		# 前驱子图
        self.parent[beginWord] = None
        wordList = set(wordList)
        queue = collections.deque([beginWord])
        seen = set()		# 访问过的单词
        seen.add(beginWord)
        next_level = set()		# 下一层要判断的单词
        length = len(beginWord)
        tag = 0			# 用来判断何时退出深度优先搜索
        
        while queue:
            num = len(queue)
            while num:
                num -= 1
                curr = queue.popleft()
                curr_li = list(curr)
                for i in range(length):
                    char = curr_li[i]
                    for j in string.ascii_lowercase:
                        curr_li[i] = j
                        word = "".join(curr_li)
                        if word not in seen and word in wordList:
                            self.parent[word].add(curr)
                            next_level.add(word)
                            if word == endWord:
                                tag = 1            
                    curr_li[i] = char
            if tag == 1:
                break
            seen |= next_level
            queue.extend(list(next_level))
            next_level.clear()
        if self.parent[endWord]:
            self.dfs(endWord, [endWord])
        return self.res

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值