我正在研究leetcode问题“ wordLadder”
给出两个单词( beginWord 和 endWord ),以及字典的单词列表,找到从 beginWord 到的最短转换序列的长度。 em> endWord ,例如:
- 一次只能更改一个字母。
- 每个转换的单词都必须存在于单词列表中。请注意, beginWord 不是 转换后的单词。
注意:
- 如果没有这样的转换序列,则返回0。
- 所有单词的长度相同。
- 所有单词仅包含小写字母字符。
- 您可以假定单词列表中没有重复项。
- 您可能认为 beginWord 和 endWord 是非空的并且不相同。
示例1:
Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"] Output: 5 Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", return its length 5.
示例2:
Input: beginWord = "hit" endWord = "cog" wordList = ["hot","dot","dog","lot","log"] Output: 0 Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.
我的解决方案
class Solution:
def ladderLength(self, beginWord, endWord, wordList):
visited = set()
wordSet = set(wordList)
queue = [(beginWord, 1)]
while len(queue) > 0:
word, step = queue.pop(0)
logging.debug(f"word: {word}, step:{step}")
#base case
if word == endWord:
return step #get the result.
if word in visited: #better than multiple conditions later.
continue
for i in range(len(word)):
for j in range(0, 26):
ordinal = ord('a') + j
next_word = word[0:i] + chr(ordinal) + word[i + 1:]
logging.debug(f"changed_word: {next_word}")
if next_word in wordSet:
queue.append((next_word, step + 1))
visited.add(word) # paint word as visited
return 0
要用尽所有可能的单词组合
我阅读了讨论区,全部采用了切片技术
next_word = word[0:i] + chr(ordinal) + word[i + 1:]
还有其他解决方案可以解决该问题吗?
答案 0 :(得分:1)
这是一个经典的网络问题。您应该做的是生成一个平方矩阵,其尺寸等于词典中单词的数量。然后用单词填充矩阵,只要单词是彼此相对的一个字母转换即可。
network['hot']['not'] = 1
所有其他单元格都必须为0
。
现在,您定义了网络,可以使用最短路径算法(例如Dijkstra)来解决问题
答案 1 :(得分:1)
您可以使用levenshtein距离(信用:This Answer)作为度量标准来了解确切的距离。在Wikipedia页面上:
Levenshtein距离是用于测量 两个序列之间的差异。非正式地讲,Levenshtein距离 两个单词之间是单字符编辑的最小数量 (插入,删除或替换)更改一个单词所需的信息 进入另一个。
如下:
def levenshteinDistance(s1, s2):
if len(s1) > len(s2):
s1, s2 = s2, s1
distances = range(len(s1) + 1)
for i2, c2 in enumerate(s2):
distances_ = [i2+1]
for i1, c1 in enumerate(s1):
if c1 == c2:
distances_.append(distances[i1])
else:
distances_.append(1 + min((distances[i1], distances[i1 + 1], distances_[-1])))
distances = distances_
return distances[-1]
然后,您可以简单地使用levenshtein距离来筛选出彼此相距一个字符的对,例如:
new_list= []
mylist = [beginWord].__add__(wordList)
for idx1, elem1 in enumerate(mylist):
for idx2, elem2 in enumerate(mylist):
if levenshteinDistance(elem1,elem2) == 1 and idx1 < idx2:
new_list.append((elem1,elem2))
new_list
哪个输出:
[('hit', 'hot'),
('hot', 'dot'),
('hot', 'lot'),
('dot', 'dog'),
('dot', 'lot'),
('dog', 'log'),
('dog', 'cog'),
('lot', 'log'),
('log', 'cog')]
然后,您可以使用此列表来找出最短的路径。每次您只需要简单地在手中搜索元组的后一个条目,就成为下一个的第一个条目。您可以在距离逻辑或最后一部分中添加对endword
的检查。