Problem Link:

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

Two typical techniques are inspected in this problem:

  1. Hash Table. One hash set is the words dictionary where we can check if a word is in the dictionary in O(1) time. The other hash set is used to store all visited words we already checked.
  2. Double-direction BFS. To accelerate the process that finds the shortest path between start word and end word, we need carry on a special BFS from both start word and end word. If there exists a path between start word and end word, then two fronts must meet at some time.

One simple solution for this problem is BFS from the start word, we keep a list of edge words (the last word of each path). Each time, we search all unvisited words next to the edge words, and add these new found words into the new edge list. The program return the length of the path when the end words is reached, or return 0 if no unvisited words can be found.

However, I implemented this BFS but got a TLE. So I adapted a double-direction BFS which may half the running time, and is accepted by the leetcode judge. The algorithm can go as follows.

Let start_front be the list of edge words of BFS paths from the start word
Let end_front be the list of edge words of BFS paths from the end word
Initialize start_front = [start] and end_front = [end]
Start a double direction BFS loop, in each iteration we extend the two fronts as follows:
  For each word w in start_front
    Find all transformable words of w those are not visited yet
  Let all new found words be the new start_font, return 0 if no new words found
  If two fronts meet, then return the number of transforms
  For each word w in end_front
    Find all transformable words of w those are not visited yet
  Let all new found words be the new end_front, return 0 if no new words found
  If two fronts meet, then return the number of transforms

The following code is the python implementatation which is accepted by leetcode.com.

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):
"""
Suppose start, end, and all words in dict are of the same length.
Then we apply BFS from both start and end, and keep track of the two front edges.
If the two front meet, then there is a path from start to end.
The algorithm can go as follows.
1) Let start_front be the list of words on the edge BFS from start word;
2) Let end_front be the list of words on the edge BFS from end word;
3) Initialize start_front = [start] and end_front = [end]
4) Start a loop where each iteration we do extend two fronts and check if they meet:
1a) Extend the start front to unvisited words
1b) If the start front cannot be extent, it means there is no path between start and end,
then return 0.
1c) If the two fronts meet, then return (transform_number + 1)
2a) Extend the end front to unvisited words
2b) If the end front cannot be extent, then return 0
2c) If the two front meet, then return (transform_number + 1)
"""
# Special cases
if start == end:
return 1 # The length of words
WORD_LENGTH = len(start) # Initialize the two fronts
start_front = [start]
end_front = [end] # Initialize the number of transforms
counter = 0 # Initialize the set of visited words
visited = set()
visited.add(start)
visited.add(end) # Extend the two fronts and check if they can meet
while True:
# Extend the start front
new_front = []
# Suppose the start front can extend
counter += 1
# Check all unvisited words transformed from the start front
for w in start_front: # Each word in the start front
for i in xrange(WORD_LENGTH): # Each character in the word
for candidate in [w[:i]+chr(97+c)+w[i+1:] for c in xrange(26)]:
# Check if two fronts can meet
if candidate in end_front:
return counter + 1
# Find all unvisited words from the front and add them as new front
if candidate in dict and candidate not in visited:
new_front.append(candidate)
visited.add(candidate)
# Check if there exists any word for the new front
if new_front:
start_front = new_front
else:
return 0 # Extend the end front
new_front = []
# Suppose the end front can extend
counter += 1
# Check all unvisited words transformed from the end front
for w in end_front: # Each word in the end front
for i in xrange(WORD_LENGTH): # Each character in the word
for candidate in [w[:i]+chr(97+c)+w[i+1:] for c in xrange(26)]:
# Check if two fronts can meet
if candidate in start_front:
return counter + 1
# Find all unvisited words from the front and add them as new front
if candidate in dict and candidate not in visited:
new_front.append(candidate)
visited.add(candidate)
# Check if there exists any word for the new front
if new_front:
end_front = new_front
else:
return 0

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

  1. 【LeetCode OJ】Word Ladder II

    Problem Link: http://oj.leetcode.com/problems/word-ladder-ii/ Basically, this problem is same to Wor ...

  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】Reverse Words in a String

    Problem link: http://oj.leetcode.com/problems/reverse-words-in-a-string/ Given an input string, reve ...

  5. 【LeetCode OJ】Interleaving String

    Problem Link: http://oj.leetcode.com/problems/interleaving-string/ Given s1, s2, s3, find whether s3 ...

  6. 【LeetCode OJ】Validate Binary Search Tree

    Problem Link: https://oj.leetcode.com/problems/validate-binary-search-tree/ We inorder-traverse the ...

  7. 【LeetCode OJ】Recover Binary Search Tree

    Problem Link: https://oj.leetcode.com/problems/recover-binary-search-tree/ We know that the inorder ...

  8. 【LeetCode OJ】Same Tree

    Problem Link: https://oj.leetcode.com/problems/same-tree/ The following recursive version is accepte ...

  9. 【LeetCode OJ】Symmetric Tree

    Problem Link: https://oj.leetcode.com/problems/symmetric-tree/ To solve the problem, we can traverse ...

随机推荐

  1. Runner站立会议之个人会议(冲刺二)

    2016.5.23 今天开会确定了接下来的目标,完成收集相关数据任务 明天要寻找类型对应的按钮图标 遇到的问题:数据中男女生,有无恋爱,区域限制均可能导致计划部分有出入 2016.5.24 今天查询相 ...

  2. HDU----(2157)How many ways??(快速矩阵幂)

    How many ways?? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  3. MFC学习之窗口基础

    WinMain函数 1.句柄(HANDLE):{ 1. 定义:资源的标识 2. 句柄的作用: 操作系统通过句柄来找到对应的资源,从而对这些资源进行管理和操作. 3句柄的分类:(按资源){ 1.图标句柄 ...

  4. 南阳OJ----Binary String Matching

    Binary String Matching 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 Given two strings A and B, whose alp ...

  5. 探究linux文件

    一.Linux的文件: 文件名区分大小写:Linux没有文件拓展名:文件名支持长文件名,含空格,少部分标点符号. - _最好不要用空格 1 GUI图形用户界面:让简单的问题更加简单: CLI命令行界面 ...

  6. oAuth协议学习

    我们的项目需要为一个认证网站开发一套API,这些API可以提供给很多公司来调用,但是公司在调用之前,必须先做授权认证,由此接触到了oAuth协议. 以下内容来自网络整理 定义 OAUTH协议为用户资源 ...

  7. java作业——整数相加

    设计思路:由于命令行参数都是字符串,所以解决问题的关键在于字符串和整数之间的转化.首先定义数组,让所要相加的数组成一个数组,然后实现数组的字符串转化为整数,最后相加输出就行了. 程序流程图: 源代码: ...

  8. juery 选择器 选择多个元素

    使用,号: $("#goodSource,#mailState") 选择了id为goodSource或者mailState的元素,当两者之间有任何一个有改变时,将会触发该操作. / ...

  9. Octopus系列之如何让前台的js脚本变得灵活重用

    Octopus系列如何让前台的js脚本变得灵活,重用 方式1:ajax方式 方式2:form表单方式 面向对象的脚本封装 jQuery的封装 做Web开发的少不了前台Ajax的使用, 返回true:f ...

  10. web开发-服务器Controller到前端中的数据传递

    一, ajax方式 (一)controller中 1. 定义AjaxResponse类 成员有: status , message, data.  其中 status是成功或失败状态, message ...