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. iOS开发数据库SQLite的使用

    iOS系统自带Core Data来进行持久化处理,而且Core Data可以使用图形化界面来创建对象,但是Core Data不是关系型数据库,对于Core Data来说比较擅长管理在设备上创建的数据持 ...

  2. 张艾迪Eidyzhang:解码天才Eidyzhang的诞生

    AOA解码:天才Eidyzhang的诞生AOA深度解读:世界第一天才Eidyzhang: (TheWorldNo.1Girl+TheWorldNo.1InterentGirl+世界第一女孩+世界第一互 ...

  3. MATLAB实现矩阵分块相乘

    要实现一下功能,这里$\bf{x}_i$为行向量 $${\bf{A}} = \left[ \begin{array}{l}{{\bf{x}}_1}\\{{\bf{x}}_2}\end{array} \ ...

  4. SQL Server数据库(表的创建)

    表的创建 1.创建列(字段):列名+类型 2.设置主键列:能够唯一表示一条数据 3.设置唯一键:设计--索引/键--添加--唯一键(选择列)--确定 唯一键的内容不能重复 4.外键关系:一张表(从表) ...

  5. iOS开发零碎笔记

    Mac常用操作 全屏截图:同时按住键盘左下方的command和shift   ,然后点击键盘上方的数字键3,便可对整个屏幕截图,截图会自动保存在桌面:任意部分截图:同时按住键盘左下方的ommand和s ...

  6. BZOJ4007 [JLOI2015]战争调度

    根本想不出来... 原来还是暴力出奇迹啊QAQ 无限ymymym中 /************************************************************** Pr ...

  7. 网站开发中必备的8个 jQuery 效果【附源码】

    jQuery 作为最优秀 JavaScript 库之一,改变了很多人编写 JavaScript 的方式.它简化了 HTML 文档遍历,事件处理,动画和 Ajax 交互,而且有成千上万的成熟 jQuer ...

  8. mysql的部分命令图解

    1.查询有哪些库: show databases;  图中除了Carlton库之外,其它都是系统自带的. 要养成在命令后加入:的习惯 2.查看某个库的表 show tables; 3. 查看表的字段 ...

  9. 绑定本地Service并与之通信-----之一

    import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os. ...

  10. Unity3d之MonoBehaviour的可重写函数整理

    最近在学习Unity3d的知识.虽然有很多资料都有记录了,可是我为了以后自己复习的时候方便就记录下来吧!下面的这些函数在Unity3d程序开发中具有很重要的作用. Update 当MonoBehavi ...