Leet Code OJ 127. Word Ladder [Difficulty: Medium]-python3

本文探讨了Python中使用Dictionary进行高效查找的优势,并通过具体案例分析了如何利用Dijkstra算法和广度优先搜索(BFS)解决单词转换问题。文章详细介绍了算法实现步骤,包括如何缩小字母查找范围以提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • dictionary查找的优越性
    python 中dictionary和list的查找机制不同,dictionary的查找hashmap,时间效率是O(1),list查找是挨个对比时间效率是O(n),所以使用list来查找的话时间效率远不如dictionary乐观。
    127这道题,好像是经过多次变迁的题目,之前题目中的的wordlist是dictionary类型,所以这道题如果将list转为dictionary来进行处理的话就能将超时的代码AC,所以第一大关键就是dictionary的查找

  • 字母查找范围缩小
    对每个单词各自对应位置出现过的字母进行统计之后在缩小后的这个范围内。

  • dijistra或广搜 (递归和迭代)
    这个题可以给用dijistra的最短路径和广搜方法来解决,思路是一致。针对当前单词与它一个字母之差的单词进行比较,并且如果它在wordlist当中,就将它作为当前单词,直到找到endword。

    dijistra方法使用了两个列表,new_list是上次产生的要访问的新词,unreached是待考察的list。每次考察结束后的只与new_list中的单词有一个字母之差的词构成下一次递归的new_list。递归方法消耗的时间还是比较多的

class Solution(object):
    def ladderLength(self, beginWord, endWord, wordList):
        """
        :type beginWord: str
        :type endWord: str
        :type wordList: List[str]
        :rtype: int
        """



        def dijkstra(new_list,unreached_list,endWord,count):
            #new_list 就是当前要来进行考察的词

            if len(unreached_list)==0  or len(new_list)==0:
                #unreached_list为空表示都已经考察结束了,new_list为空表示上一次考察没有结果
                return 0

            count = count + 1  #这已经是新一轮的考察
            list_return = {}#下一次要考察的对象,所以每次都弄成空的
            #print('newlist', new_list)
            #print('dijistra', unreached_list)

            for i in new_list.keys():#d对每个单词进行同样的处理
                for j in range(len(endWord)):#对这个单词的每个字母变化
                    for k in self.dic1[j]:#for k in character #这个方法在26个字母中找比较慢一点
                        #对这个单词每个字母可能的变化变化
                        temp = i
                        tmp1 = temp[:j]
                        tmp2 = temp[j+1:]
                        temp = tmp1+k+tmp2 #得到的新的改变单词的结果
                        if temp==i:
                            continue
                        else:
                            if temp in unreached_list:#说明变化后的结果是存在的
                                list_return[temp] = 0
                                #print('list_return', list_return)
                                if temp==endWord:
                                    return count
                                del unreached_list[temp] #这个单词已经是匹配过的了
            return dijkstra(list_return,unreached_list,endWord,count)

        character = 'abcdefghijklmnopqrstuvwxyz'
        begin = {}
        begin[beginWord] = 0
        dict_unreach = {}
        #首先先将整个wordlist 变成字典

        self.dic1 = []
        length = len(wordList[1])

        #对范围缩小一下
        for j in range(length):
            temp = []
            for i in range(len(wordList)):
                if temp.count(wordList[i][j]) == 0:
                    temp.append(wordList[i][j])
            self.dic1.append(temp)


        for i in range(len(wordList)):
            if wordList[i] not in dict_unreach:
                dict_unreach[wordList[i]] = 1
           # print(dict_unreach)
        return dijkstra(begin, dict_unreach, endWord, 1)



  • 使用广搜的方法,广搜用到了队列这种数据结构。python中的队列:import queue queue.Queue(),对应的操作函数是:q.put() q.get()
import queue
class Solution(object):
    def ladderLength(self, beginWord, endWord, wordList):
        """
        :type beginWord: str
        :type endWord: str
        :type wordList: Set[str]
        :rtype: int
        """
        #广搜

        ans,dic1,wordList0 = queue.Queue() ,{} ,{}# 创建一个队列

        if wordList.count(endWord) == 0:
            return 0

        for i in range(len(wordList)):
            wordList0[wordList[i]] = 0


        ans.put(beginWord)  # 首先先把第一个词压入
        dic1[beginWord] = 1

        length  = len(beginWord)
        wo = []

        for t in range(length):
            wo1 =[]
            for k in range(len(wordList)):
                if wo1.count(wordList[k][t]) == 0:
                    wo1.append(wordList[k][t])
            wo.append(wo1)
       # print(wo)


        while not ans.empty() :
            temp = ans.get()
            if temp == endWord:
                return dic1[endWord]

            for i in range(length):
                temp1 = temp[:i]
                temp2 = temp[i+1:]
                for j in wo[i]:
                    if temp[i] != j:
                        result = temp1+j+temp2
                        if result in wordList0:
                             ans.put(result)
                             dic1[result] = dic1[temp]+1
                             #print(result,end=" ")

                             del wordList0[result]

        return 0

还是考察了基本的数据结构的使用(队列),和广搜的操作。一个字母变化单词的比较也是比较巧妙的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值