127. 单词接龙

题目-困难难度

字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> … -> sk:

每一对相邻的单词只差一个字母。
对于 1 <= i <= k 时,每个 si 都在 wordList 中。注意, beginWord 不需要在 wordList 中。
sk == endWord
给你两个单词 beginWord 和 endWord 和一个字典 wordList ,返回 从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0 。

示例

示例 1:

  • 输入:beginWord = “hit”, endWord = “cog”, wordList = [“hot”,“dot”,“dog”,“lot”,“log”,“cog”]
    输出:5
    解释:一个最短转换序列是 “hit” -> “hot” -> “dot” -> “dog” -> “cog”, 返回它的长度 5。

示例 2:

  • 输入:beginWord = “hit”, endWord = “cog”, wordList = [“hot”,“dot”,“dog”,“lot”,“log”]
    输出:0
    解释:endWord “cog” 不在字典中,所以无法进行转换。

提示:

  • 1 <= beginWord.length <= 10
  • endWord.length == beginWord.length
  • 1 <= wordList.length <= 5000
  • wordList[i].length == beginWord.length
  • beginWord、endWord 和 wordList[i] 由小写英文字母组成
  • beginWord != endWord
  • wordList 中的所有字符串 互不相同

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/summary-ranges
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

1. bfs

时间
388ms
击败 53.49%使用 Python3 的用户
内存
16.85MB
击败 76.93%使用 Python3 的用户

class Solution:
    def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
        # 将wordList去重
        wordList = set(wordList)
        # 如果查询的单词不存在于wordList中,直接返回0
        if endWord not in wordList:
            return 0
        # 初始查询的单词
        q = {beginWord}
        # 初始化步骤, 最低为2
        step = 2
        # 遍历单词
        while q:
            # 用于存储下一次遍历单词
            tmp = set()
            # 对于q中的单词
            for word in q:
                # 依次遍历单词的每一个字母
                for i in range(len(word)):
                    # 替换单词的当前字母为a-z中其他的字母
                    for c in 'abcdefghijklmnopqrstuvwxyz':
                        # 生成替换后的新单词
                        newWord = word[:i] + c + word[i+1:]
                        # 如果替换后的单词就是目标单词
                        if newWord == endWord:
                            # 返回最终步骤数
                            return step
                        # 如果不是目标单词, 但是存在于单词列表中
                        if newWord in wordList:
                            # 添加到下次遍历
                            tmp.add(newWord)
                            # 从单词列表中移除当前单词, 防止重复
                            wordList.remove(newWord)
            # 给q赋值下次需要遍历的单词
            q = tmp
            # 步骤数+1
            step += 1
        # 未能找到则返回0
        return 0

2. bfs

超出时间限制

class Solution:
    def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
        # 判断两个单词是否只有一个不同的方法
        def oneDiff(l1,l2):
            return sum(i!=j for i,j in zip(l1,l2)) == 1

        # 获取wordList长度
        lwl = len(wordList)
        # 创建列表存储相关联并且一字之差的单词
        adj = [[] for _ in range(lwl)]
        # 为获取目标索引初始化一个索引
        endIndex = -1
        # 遍历列表项
        for i, s in enumerate(wordList):
            # 如果当前单词为目标单词, 获取它的索引
            if s == endWord:
                endIndex = i
            # 将每个单词相差一个单词的单词, 放到关联链表
            for j in range(i + 1, lwl):
                if oneDiff(s, wordList[j]):
                    adj[i].append(j)
                    adj[j].append(i)
        # 如果查询的单词不存在于结果列表内, 返回0 
        if endIndex == -1:
            return 0
        # 遍历找出与查询单词相近的单词
        q = [i for i, s in enumerate(wordList) if oneDiff(beginWord, s)]
        # 存储遍历过的单词
        vis = set(q)
        # 如果第一个就找到, 说明转换序列的长度为2
        step = 2
        # 遍历开始
        while q:
            # tmp获取q列表
            tmp = q
            # 将q列表赋值为空方便添加下一级遍历的单词
            q = []
            # 遍历最相近的单词
            for cur in tmp:
                # 如果找到了目标单词, 返回步数
                if cur == endIndex:
                    return step
                # 如果没找到, 遍历当前相近单词下的第二层相近的单词
                for nxt in adj[cur]:
                    # 确保单词未被遍历的情况下,添加下一次遍历的单词
                    if nxt not in vis:
                        vis.add(nxt)
                        q.append(nxt)
            step += 1
        return 0
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值