赞
踩
给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:
说明:
输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]
输出: 5
解释: 一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
返回它的长度 5。
整体思路:求最短序列长度==>想到图模型==>想到广度优先搜索
构建图思路:
效果图示:
方法一代码解释:
虚拟节点。对于单词 hit,我们创建三个虚拟节点 *it、h*t、hi*,
并让 hit 向这三个虚拟节点分别连一条边即可。如果一个单词能够转化为 hit,
那么该单词必然会连接到这三个虚拟节点之一。对于每一个单词,
我们枚举它连接到的虚拟节点,
把该单词对应的 id 与这些虚拟节点对应的 id 相连即可。
举例解释:对于如:“hit"与“hot”这种相差一个字符的单词,共同连接“hit”所指向的三个边之一的虚拟节点"h*t”,由此方法,将所有仅差一个字母的单词节点相互连接。
注意:因为添加了虚拟节点,所以我们得到的距离为实际最短路径长度的两倍。 在最终结果需要返回当前距离一般减一的结果
本题中,使用双向队列实现广度优先遍历:
import collections from collections import defaultdict class Solution: def ladderLength( beginWord, endWord, wordList) -> int: def addWord(word: str): # 计数结点总数 if word not in wordId: nonlocal nodeNum # nonlocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量。表示在一个总def中做同一变量 # print(nodeNum) wordId[word] = nodeNum # print(word) # word 表示单词 nodeNum += 1 def addEdge(word: str): # 创建图 addWord(word) id1 = wordId[word] # id2是真实结点的结点编号 chars = list(word) for i in range(len(chars)): tmp = chars[i] chars[i] = "*" newWord = "".join(chars) # 组成新的单词 addWord(newWord) # 为虚拟单词建立虚拟结点 id2 = wordId[newWord] # id2是虚拟结点的结点编号 edge[id1].append(id2) # edge是字典,将此虚拟结点的词连接真实结点中 # print(edge) edge[id2].append(id1) # 双向连接,形成双向图 chars[i] = tmp # 恢复单词 wordId = dict() edge = collections.defaultdict(list) # Python内建字典类(dict)的一个子类 (class list)表示边 nodeNum = 0 # -------------------------------------------------------- for word in wordList: addEdge(word) # 对单词字典列表中的单词插入边与结点 addEdge(beginWord) # 将首个单词加入图中与对应虚拟结点加入图中 # 创建图完毕 # -------------------------------------------------------- # 当给出结尾词不在字典中,必无最短路径 if endWord not in wordId: return 0 dis = [float("inf")] * nodeNum beginId, endId = wordId[beginWord], wordId[endWord] # 获得开始结束单词的id # print(beginId, endId) dis[beginId] = 0 # 将距离中的beginId设置为 0 que = collections.deque([beginId]) # 实现双端队列 while que: x = que.popleft() if x == endId: return dis[endId] // 2 + 1 for it in edge[x]: # 从开始结点开始寻找,实现广度优先遍历 if dis[it] == float("inf"): dis[it] = dis[x] + 1 print(it,dis[it]) que.append(it) return 0
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。