Python|每日一练|单词接龙|最短转换序列|单向|广度优先搜索:单词接龙

题目:

字典 wordList 中从单词 beginWord  endWord  转换序列 是一个按下述规格形成的序列:

        wordList是一个英文单词,意思是“单词列表”。如果您需要查找字典,可以使用在线词典,例如柯林斯词典、有道词典等。这些在线词典可以帮助您查找单词的定义、拼写、发音等信息。

  • 序列中第一个单词是 beginWord 。
  • 序列中最后一个单词是 endWord 。
  • 每次转换只能改变一个字母。
  • 转换过程中的中间单词必须是字典 wordList 中的单词。

给你两个单词 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
  • beginWordendWord 和 wordList[i] 由小写英文字母组成
  • beginWord != endWord
  • wordList 中的所有字符串 互不相同

完整代码及注释(基于选项D):

class Solution(object):
    def __init__(self):
        self.count = 0
    def ladderLength(self, beginWord, endWord, wordList):
        """
        :type beginWord: str
        :type endWord: str
        :type wordList: List[str]
        :rtype: int
        """
        # •	序列中最后一个单词是 endWord,如果endWord not in wordList则返回0
        #
        if endWord not in wordList:
            return 0
        # •	若序列中第一个单词就是 beginWord,则从wordlist中移除,beginWord 不需要在 wordList 中。
        # wordList = ["hot", "dot", "dog", "lot", "log", "cog"]
        if beginWord in wordList:
            wordList.remove(beginWord)
        wordDict = dict()
        #wordList中每个单词遍历,按同一位置具有相同字母的map如下:
        #本例子哈希:{'_ot': ['hot', 'dot', 'lot'], 'h_t': ['hot'], 'ho_': ['hot'], 'd_t': ['dot'], 'do_': ['dot', 'dog'],
        # '_og': ['dog', 'log', 'cog'], 'd_g': ['dog'], 'l_t': ['lot'], 'lo_': ['lot', 'log'], 'l_g': ['log'], 'c_g': ['cog'], 'co_': ['cog']}
        for word in wordList:
            #当前单词每个字母遍历
            for i in range(len(word)):
                #按顺序将当前词中每个字母轮流替换成“_”并临时存储在tmp中
                tmp = word[:i] + "_" + word[i + 1 :]
                #将tmp作为key,存储在字典中,对应的值为同一位置存在该key的所有单词,即某一位置具有相同字母的单词归类
                wordDict[tmp] = wordDict.get(tmp, []) + [word]
        #然后在基于wordList的map中查找是否有temp,如果存在temp,则把temp添加到queue当中,还是别忘了要将当前的“hit”从队列中remove掉,
        # 并把相应的visited设置已以访问过,采用set方法,访问过就有记录,自动去重,不记录已访问次数。
        stack, visited = [(beginWord, 1)], set()
        while stack:
            #如果stack不为空,则 stack分解为word和step
            word, step = stack.pop(0)
            #如果word未被访问过,则记录
            if word not in visited:
                visited.add(word)
                #如果是结尾单词,则返回锁经历的搜索次数
                if word == endWord:
                    return step
                for i in range(len(word)):
                    tmp = word[:i] + "_" + word[i + 1 :]
                    #python dict.get“Python中的字典(Dictionary)是以键值对的形式存储数据的,get()方法可以返回指定键的值,如果该键不存在的话,返回默认值。
                    # 语法 dict.get(key, default=None) 参数 key:需要查找的键。 default:如果查找的键不存在的话,返回default的值。默认为None。
                    #该方法取得具有同样词根的一组词,如果没有,则返回空,
                    neigh_words = wordDict.get(tmp, [])
                    for neigh in neigh_words:
                        if neigh not in visited:
                            #如果没有访问过(即出现新的路径),则是一条有效搜索路径,可将该word添加入stack,并且更新step
                            #同级的不同单词,step记录一致
                            stack.append((neigh, step + 1))
        return 0

if __name__ == '__main__':
    s = Solution()
    beginWord = "hit"
    endWord = "cog"
    wordList = ["hot", "dot", "dog", "lot", "log", "cog"]
    result=s.ladderLength(beginWord, endWord, wordList)
    print(result)

说明:

 # •    序列中最后一个单词是 endWord,如果endWord not in wordList则返回0
        #
        if endWord not in wordList:
            return 0
        # •    若序列中第一个单词就是 beginWord,则从wordlist中移除,beginWord 不需要在 wordList 中。
        # wordList = ["hot", "dot", "dog", "lot", "log", "cog"]
        if beginWord in wordList:
            wordList.remove(beginWord)
        wordDict = dict()
        #wordList中每个单词遍历,按同一位置具有相同字母的map如下:
        #本例子哈希:{'_ot': ['hot', 'dot', 'lot'], 'h_t': ['hot'], 'ho_': ['hot'], 'd_t': ['dot'], 'do_': ['dot', 'dog'],
        # '_og': ['dog', 'log', 'cog'], 'd_g': ['dog'], 'l_t': ['lot'], 'lo_': ['lot', 'log'], 'l_g': ['log'], 'c_g': ['cog'], 'co_': ['cog']}
        for word in wordList:
            #当前单词每个字母遍历
            for i in range(len(word)):
                #按顺序将当前词中每个字母轮流替换成“_”并临时存储在tmp中
                tmp = word[:i] + "_" + word[i + 1 :]
                #将tmp作为key,存储在字典中,对应的值为同一位置存在该key的所有单词,即某一位置具有相同字母的单词归类
                wordDict[tmp] = wordDict.get(tmp, []) + [word]
        #然后在基于wordList的map中查找是否有temp,如果存在temp,则把temp添加到queue当中,还是别忘了要将当前的“hit”从队列中remove掉,
        # 并把相应的visited设置已以访问过,采用set方法,访问过就有记录,自动去重,不记录已访问次数。
        stack, visited = [(beginWord, 1)], set()
        while stack:
            #如果stack不为空,则 stack分解为word和step
            word, step = stack.pop(0)
            #如果word未被访问过,则记录
            if word not in visited:
                visited.add(word)
                #如果是结尾单词,则返回锁经历的搜索次数
                if word == endWord:
                    return step
                for i in range(len(word)):
                    tmp = word[:i] + "_" + word[i + 1 :]
                    #python dict.get“Python中的字典(Dictionary)是以键值对的形式存储数据的,get()方法可以返回指定键的值,如果该键不存在的话,返回默认值。
                    # 语法 dict.get(key, default=None) 参数 key:需要查找的键。 default:如果查找的键不存在的话,返回default的值。默认为None。
                    #该方法取得具有同样词根的一组词,如果没有,则返回空,
                    neigh_words = wordDict.get(tmp, [])
                    for neigh in neigh_words:
                        if neigh not in visited:
                            #如果没有访问过(即出现新的路径),则是一条有效搜索路径,可将该word添加入stack,并且更新step
                            #同级的不同单词,step记录一致

其他三个选项的错误均出现在while stack循环体中,具体为:

A、选项代码局部:

        while stack:
            word, step = stack.pop(0)
            if word not in visited:
                visited.add(word)
                if word == endWord:
                    return step
                for i in range(len(word)):
                    #字符的连接符号应为+,*是针对数值计算的
                    tmp = word[:i] * "_" * word[i * 1 :]
                    neigh_words = wordDict.get(tmp, [])
                    for neigh in neigh_words:
                        if neigh not in visited:
                            stack.append((neigh, step + 1))
        return 0

B、选项代码局部:

        while stack:
            word, step = stack.pop(0)
            if word not in visited:
                visited.add(word)
                #错误点: word < endWord错误,应该是处理到最后一个单词(word == endWord)再return
                if word < endWord:
                    return step
                for i in range(len(word)):
                    tmp = word[:i] + "_" + word[i + 1 :]
                    neigh_words = wordDict.get(tmp, [])
                    for neigh in neigh_words:
                        if neigh not in visited:
                            stack.append((neigh, step + 1))
        return 0

C、选项代码局部:

while stack:
    word, step = stack.pop(0)
    if word not in visited:
        visited.add(word)
        if word == endWord:
            return step
        for i in range(len(word)):
            tmp = word[:i] + "_" + word[i + 1 :]
            neigh_words = wordDict.get(tmp, [])
            for neigh in neigh_words:
                #语法错误:and in不能连用
                if neigh and in visited:
                    stack.append((neigh, step + 1))
return 0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

打酱油的工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值