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. python与unicode

    Unicode是一种在计算机上使用的字符编码,是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言.跨平台进行文本转换.处理的要求. Uni ...

  2. hdu-----(1507)Uncle Tom's Inherited Land*(二分匹配)

    Uncle Tom's Inherited Land* Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (J ...

  3. 20145236 《Java程序设计》实验二实验报告

    北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1452 指导教师:娄嘉鹏 实验日期:2016.04.08 实验名称: Java面向对象程序设计 实验内容: 初步掌握单元测试和T ...

  4. SAP资产明细报表

    前两年别人写的,无自定义表字段...直接使用: *&---------------------------------------------------------------------* ...

  5. EF Code First 学习笔记:关系

      一对多关系 项目中最常用到的就是一对多关系了.Code First对一对多关系也有着很好的支持.很多情况下我们都不需要特意的去配置,Code First就能通过一些引用属性.导航属性等检测到模型之 ...

  6. redhat enterprixe 5.0 web 服务配置与管理

    一.Web服务及工作原理 Web服务的实现采用客户/服务器模型.客户机运行Web客户程序(浏览器),作用是解释和显示Web页面,相应用户的输入请求,并且通过http协议将用户请求传递给Web服务器.W ...

  7. CentOS hadoop启动错误 JAVA_HOME is not set and could not be found

    ... Starting namenodes on [] localhost: Error: JAVA_HOME is not set and could not be found. localhos ...

  8. HTML5表单新增属性

    1.form 原来html里面,表单里的元素应该包裹在表单里,如 <form action="login.php" method="get"> &l ...

  9. [Js]布局转换

    为什么要布局转换? 要这样的效果,单写css,只要给每个li浮动就行,不需要绝对定位.但是比如做一些效果(如鼠标移入图片变大),就需要改变位置了.直接给每个li在css上定好位置不方便,也不知道有几个 ...

  10. struts2最新s2-016代码执行漏洞CVE-2013-2251

    这是一个代码执行漏洞,利用java代码来执行系统命令.   影响版本:Struts 2.0.0 – Struts 2.3.15   漏洞说明: The Struts 2 DefaultActionMa ...