[Lintcode]120. Word Ladder /[Leetcode]127. Word Ladder
120. Word Ladder / 127. Word Ladder
- 本题难度: Hard/Medium
- Topic: Data Structure
Description
Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:
Only one letter can be changed at a time
Each intermediate word must exist in the dictionary
Example
Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.
Notice
Return 0 if there is no such transformation sequence.
All words have the same length.
All words contain only lowercase alphabetic characters.
我的代码
from collections import deque
class Solution(object):
def ladderLength(self, beginWord, endWord, wordList):
def getDic(wordList):
d = {}
for word in wordList:
for i in range(len(word)):
s = word[:i] + '#' + word[i + 1:]
d[s] = d.get(s, []) + [word]
return d
def bfs(beginWord, endWord, wordList):
# 1.不要出现圈
visited = set(beginWord)
# 2.记录走了多少步
q = collections.deque([[beginWord, 1]])
# 3.某个单词,改变某个位置,有多少个单词
d = getDic(wordList)
#print(d)
while q:
tmpW, tmpLen = q.popleft()
for i in range(len(tmpW)):
changed_word = tmpW[:i]+'#'+tmpW[i+1:]
next_words = d.get(changed_word,[] )
for next_word in next_words:
if next_word in visited:
continue
else:
#防止重复访问
visited.add(next_word)
#达到endWord
if next_word == endWord:
return tmpLen+1
else:
q.append([next_word,tmpLen+1])
return 0
if endWord==beginWord:
return 1
wordList.add(endWord)
return bfs(beginWord, endWord, wordList)
别人的代码
双端
https://github.com/illuz/leetcode/blob/master/solutions/126.Word_Ladder/AC_two_end_BFS_n.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Author: illuz <iilluzen[at]gmail.com>
# File: AC_two_end_BFS_n.py
# Create Date: 2015-03-29 15:10:46
# Usage: AC_two_end_BFS_n.py
# Descripton:
import string
class Solution:
# @param start, a string
# @param end, a string
# @param dict, a set of string
# @return an integer
def ladderLength(self, start, end, dict):
start_set, end_set = set([start]), set([end])
n = len(start)
dis = 1
chars = string.ascii_lowercase
while start_set and end_set:
dis += 1
if len(start_set) < len(end_set):
start_set, end_set = end_set, start_set
new_start_set = set()
for word in start_set:
for idx in range(n):
for c in chars:
s = word[:idx] + c + word[idx+1:]
if s in end_set:
return dis
if s in dict:
new_start_set.add(s)
dict.remove(s)
start_set = new_start_set
return 0
# debug
s = Solution()
print s.ladderLength("hot", "dog", ["hot","dog"])
思路
BFS
- 最短,可以用bfs
- change 我的理解是改变(非增删)
3. 用树的结构来理解 - 注意要防止重复
- 用字典,减少重复查询
- 出错
忘记将endword加入字典中