作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址: https://leetcode.com/problems/word-ladder/description/

题目描述:

Given two words (beginWord and endWord), and a dictionary’s word list, find the length of shortest transformation sequence from beginWord to endWord, such that:

  1. Only one letter can be changed at a time.
  2. Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

Note:

  • Return 0 if there is no such transformation sequence.
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
  • You may assume no duplicates in the word list.
  • You may assume beginWord and endWord are non-empty and are not the same.

Example 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.

Example 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.

题目大意

这个题名字是词语梯子,简单理解就是从begin开始,每次只能替换已经转化了的单词的其中一个字符,看最终能不能得到end。有个要求就是,每次变化不是任意的,是必须变成wordList中的其中一个才行。

解题方法

拿到这个题没有什么思路,看了别人解答之后,才猛然发现这个题是走迷宫问题的变形!也就是说,我们每次变化有26个方向,如果变化之后的位置在wordList中,我们认为这个走法是合规的,最后问能不能走到endWord?

很显然这个问题是BFS的问题,只是把走迷宫问题的4个方向转变成了26个方向,直接BFS会超时,所以我使用了个visited来保存已经遍历了的字符串,代表已经走过了的位置。代码总体思路很简单,就是利用队列保存每个遍历的有效的字符串,然后对队列中的每个字符串再次遍历,保存每次遍历的长度即可。

时间复杂度是O(NL),空间复杂度是O(N).其中N是wordList中的单词个数,L是其实字符串的长度。

class Solution(object):
def ladderLength(self, beginWord, endWord, wordList):
"""
:type beginWord: str
:type endWord: str
:type wordList: List[str]
:rtype: int
"""
wordset = set(wordList)
if endWord not in wordset:
return 0
visited = set([beginWord])
chrs = [chr(ord('a') + i) for i in range(26)]
bfs = collections.deque([beginWord])
res = 1
while bfs:
len_bfs = len(bfs)
for _ in range(len_bfs):
origin = bfs.popleft()
for i in range(len(origin)):
originlist = list(origin)
for c in chrs:
originlist[i] = c
transword = "".join(originlist)
if transword not in visited:
if transword == endWord:
return res + 1
elif transword in wordset:
bfs.append(transword)
visited.add(transword)
res += 1
return 0

显然上面的这个做法还是可以变短一点的,想起之前的二叉树的BFS的时候,会在每个节点入队列的时候同时保存了这个节点的深度,这样就少了一层对bfs当前长度的循环,可以使得代码变短。同时,学会了一个技巧,直接把已经遍历过的位置从wordList中删除,这样就相当于我上面的那个visited数组。下面这个代码很经典了,可以记住。

class Solution(object):
def ladderLength(self, beginWord, endWord, wordList):
"""
:type beginWord: str
:type endWord: str
:type wordList: List[str]
:rtype: int
"""
wordset = set(wordList)
bfs = collections.deque()
bfs.append((beginWord, 1))
while bfs:
word, length = bfs.popleft()
if word == endWord:
return length
for i in range(len(word)):
for c in "abcdefghijklmnopqrstuvwxyz":
newWord = word[:i] + c + word[i + 1:]
if newWord in wordset and newWord != word:
wordset.remove(newWord)
bfs.append((newWord, length + 1))
return 0

参考资料:

http://www.cnblogs.com/grandyang/p/4539768.html

日期

2018 年 9 月 29 日 —— 国庆9天长假第一天!

【LeetCode】127. Word Ladder 解题报告(Python)的更多相关文章

  1. [LeetCode] 127. Word Ladder 单词阶梯

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...

  2. leetcode 127. Word Ladder、126. Word Ladder II

    127. Word Ladder 这道题使用bfs来解决,每次将满足要求的变换单词加入队列中. wordSet用来记录当前词典中的单词,做一个单词变换生成一个新单词,都需要判断这个单词是否在词典中,不 ...

  3. Leetcode#127 Word Ladder

    原题地址 BFS Word Ladder II的简化版(参见这篇文章) 由于只需要计算步数,所以简单许多. 代码: int ladderLength(string start, string end, ...

  4. LeetCode 127. Word Ladder 单词接龙(C++/Java)

    题目: Given two words (beginWord and endWord), and a dictionary's word list, find the length of shorte ...

  5. leetcode@ [127] Word Ladder (BFS / Graph)

    https://leetcode.com/problems/word-ladder/ Given two words (beginWord and endWord), and a dictionary ...

  6. Java for LeetCode 127 Word Ladder

    Given two words (beginWord and endWord), and a dictionary, find the length of shortest transformatio ...

  7. leetcode 127. Word Ladder ----- java

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...

  8. [leetcode]127. Word Ladder单词接龙

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...

  9. [LeetCode] 127. Word Ladder _Medium tag: BFS

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...

随机推荐

  1. OOM机制

    Linux内核根据应用程序的要求分配内存,通常来说应用程序分配了内存但是并没有实际全部使用,为了提高性能,这部分没用的内存可以留作它用,这部分内存是属于每个进程的,内核直接回收利用的话比较麻烦,所以内 ...

  2. 码上来战!探索“智”感生活,HMS Core线上Codelabs挑战赛第4期开始!

    HMS Core线上Codelabs挑战赛第4期正式开始!我们向所有实践力超强.创新力满满的开发者发出邀请,用你的超级"码"力,解锁更多应用价值! 生活里,我们被手机"秒 ...

  3. dubbo 协议的 K8s pod 存活探针配置

    背景 某项目采用微服务架构,dubbo 框架,K8s 方式部署. 其中 HTTP 协议由网关应用统一处理,大部分应用仅提供 dubbo 协议. 目标 应用某个实例(pod)状态异常时,尝试自动重启恢复 ...

  4. 学习java 7.13

    学习内容: 一个汉字存储:如果是GBK编码,占用2个字节:如果是UTF-8编码,占用3个字节 汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数 字符流=字节流+编码表 采用何种规则编码,就要 ...

  5. day11 序列化组件、批量出入、自定义分页器

    day11 序列化组件.批量出入.自定义分页器 今日内容详细 ajax实现删除二次提醒(普通版本) ajax结合第三方插件sweetalert实现二次提醒(样式好看些) ajax如何发送文件数据 aj ...

  6. 【排序算法】——冒泡排序、选择排序、插入排序、Shell排序等排序原理及Java实现

    排序 1.定义: 所谓排序,即是整理文件中的内容,使其按照关键字递增或递减的顺序进行排列. 输入:n个记录,n1,n2--,其对应1的关键字为k1,k2-- 输出:n(i1),n(i2)--,使得k( ...

  7. 【Linux】【Shell】【Basic】条件测试

    1. 数值测试:数值比较 -eq:是否等于: [ $num1 -eq $num2 ] -ne:是否不等于: -gt:是否大于: -ge:是否大于等于: -lt:是否小于: -le:是否小于等于: 2. ...

  8. 【编程思想】【设计模式】【行为模式Behavioral】模板模式Template

    Python转载版 https://github.com/faif/python-patterns/blob/master/behavioral/template.py #!/usr/bin/env ...

  9. Dubbo声明式缓存

    为了进一步提高消费者对用户的响应速度,减轻提供者的压力,Dubbo提供了基于结果的声明式缓存.该缓存是基于消费者端的,所以使用很简单,只需修改消费者配置文件,与提供者无关 一.创建消费者07-cons ...

  10. 第7章 使用性能利器——Redis

    在现今互联网应用中,NoSQL已经广为应用,在互联网中起到加速系统的作用.有两种NoSQL使用最为广泛,那就是Redis和MongoDB.本章将介绍Redis和Spring Boot的结合.Redis ...