Problem Link:

http://oj.leetcode.com/problems/word-ladder-ii/

Basically, this problem is same to Word Ladder I, which uses a double-direction BFS. However, the difference is that we need to keep track of all paths during the double-direction BFS in order to output all possible shortest paths from the start word to the end word. To do this, we use the build-in dictionary strucutre in python. After the BFS, we need another normal BFS from the start word following the path dictionary, and return all paths reaching the end word.

Python performance issue. During the constructing the path dictionary, we need to check whether the key already exists. We can use dict.has_key() or key in dict.keys(), however both ways get a TLE by oj.leetcode.com. In this case, we can use dict.setdefault(key, default_value) or try...except... clause to accelerate such operations.

class Solution:
# @param start, a string
# @param end, a string
# @param dict, a set of string
# @return an integer
def findLadders(self, start, end, dict):
"""
Similar to solving WordLadder 1, we use a double-direction BFS.
However, instead of only storing the last word of each path (front edges),
we need to store the entire path.
In the code for solving WordLadder 1,
we check two fronts meet during extending the paths,
but this problem asks for all possible shortest path,
so we need to extend all paths and then check all pairs of paths from start and end.
"""
# Special cases
if start == end:
return [start] # The length of words
WORD_LENGTH = len(start) # New words in one step
new_words = set() # Initialize the set of visited words
start_front = set()
start_front.add(start)
start_visited = set()
start_visited.add(start) end_front = set()
end_front.add(end)
end_visited = set()
end_visited.add(end) # Add end to the dictionary
dict.add(end) # Traverse map
next_words = {} meet = False
# Extend the two fronts and check if they can meet
while not meet:
# Extend the start front
new_words.clear()
for w in start_front:
next_words[w] = []
for i in xrange(WORD_LENGTH):
for candidate in [w[:i]+chr(97+c)+w[i+1:] for c in xrange(26)]:
if candidate in dict and candidate not in start_visited:
next_words[w].append(candidate)
new_words.add(candidate)
if new_words:
# Update visited words
start_visited.update(new_words)
start_front = new_words.copy()
else:
return [] # Check if two fronts meet
if start_front & end_front:
break # Extend the end front
new_words.clear()
for w in end_front:
for i in xrange(WORD_LENGTH):
for candidate in [w[:i]+chr(97+c)+w[i+1:] for c in xrange(26)]:
if candidate in dict and candidate not in end_visited:
next_words.setdefault(candidate, []).append(w)
#try:
# next_words[candidate].append(w)
#except:
# next_words[candidate] = [w]
new_words.add(candidate)
if new_words:
end_visited.update(new_words)
end_front = new_words.copy()
else:
return []
# Check if two fronts meet
if start_front & end_front:
break
# BFS from start to end
res = []
path = [[start]]
while res == []:
new_path = []
for p in path:
try:
for w in next_words[p[-1]]:
new_path.append(p+[w])
if w == end:
res.append(p+[w])
except:
pass
path = new_path
# Return all paths in res
return res

【LeetCode OJ】Word Ladder II的更多相关文章

  1. 【LeetCode OJ】Word Ladder I

    Problem Link: http://oj.leetcode.com/problems/word-ladder/ Two typical techniques are inspected in t ...

  2. 【LeetCode OJ】Word Break II

    Problem link: http://oj.leetcode.com/problems/word-break-ii/ This problem is some extension of the w ...

  3. 【LeetCode OJ】Word Break

    Problem link: http://oj.leetcode.com/problems/word-break/ We solve this problem using Dynamic Progra ...

  4. 【LeetCode OJ】Path Sum II

    Problem Link: http://oj.leetcode.com/problems/path-sum-ii/ The basic idea here is same to that of Pa ...

  5. 【LeetCode OJ】Palindrome Partitioning II

    Problem Link: http://oj.leetcode.com/problems/palindrome-partitioning-ii/ We solve this problem by u ...

  6. 【LEETCODE OJ】Single Number II

    Problem link: http://oj.leetcode.com/problems/single-number-ii/ The problem seems like the Single Nu ...

  7. 【leetcode】Word Ladder II

      Word Ladder II Given two words (start and end), and a dictionary, find all shortest transformation ...

  8. 【LeetCode 229】Majority Element II

    Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorit ...

  9. 【leetcode刷题笔记】Word Ladder II

    Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from ...

随机推荐

  1. 小米域名过渡JS

    <script>jQuery(function($) { (function() { var $bnBar = $(''), $topBn = $('#J_topBn'), $topBnB ...

  2. nyoj------20吝啬的国度

    吝啬的国度 时间限制:1000 ms  |  内存限制:65535 KB 难度:3    描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市 ...

  3. 190. Reverse Bits -- 按位反转

    Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in ...

  4. struts2配置通用action一个顶N个,你还在写一大堆action吗?

    <!-- 通用action!!!约定优于配置 --> <action name="*_*" class="cn.cnsdhzzl.action.{1}A ...

  5. java下载网络图片

    import java.io.DataInputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IO ...

  6. js-分享107个js中的非常实用的小技巧(借鉴保存)

    转载原文:http://***/Show.aspx?id=285 1.document.write(""); 输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是:doc ...

  7. loadrunner 参数化数据更新方式

    数据分配方式: Select next row[选择下一行]: 顺序(Sequential):按照参数化的数据顺序,一个一个的来取. 随机(Random):参数化中的数据,每次随机的从中抽取数据. 唯 ...

  8. Octopus系列之开发过程各个技术点

    自定义了页面周期 使用唯一的一个VelocityEngine全局的静态实例,优化了小泥鳅blog中每次请求都要创建VelocityEngine实例对象,减少了对象的开销 通过UA判断请求来自的设备,从 ...

  9. 使用Matrix控制图片和组件的变化

    如下程序开发了一个自定义View,该自定义View可以检测到用户的键盘事件,当用户单击手机的方向键时,该自定义View会用Matrix对绘制的图形进行旋转.倾斜变换. import android.c ...

  10. hdu 4612 Warm up

    http://acm.hdu.edu.cn/showproblem.php?pid=4612 将原图进行缩点 变成一个树 树上每条边都是一个桥 然后加一条边要加在树的直径两端才最优 代码: #incl ...