Word Ladder II

update Jul 21, 2017 21:42

LintCodearrow-up-right LeetCodearrow-up-right

Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

Only one letter can be changed at a time Each intermediate word must exist in the dictionary

Notice

  • All words have the same length.

  • All words contain only lowercase alphabetic characters.

Example

Given:
  start = "hit"
  end = "cog"
  dict = ["hot","dot","dog","lot","log"]
Return
  [
    ["hit","hot","dot","dog","cog"],
    ["hit","hot","lot","log","cog"]
  ]

Basic Idea:

这道题目的难点是要求出所有最短路径。之前的 Word Ladder Iarrow-up-right 只要求输出最短路径的长度,我们只需要做一次BFS即可,但是现在要求所有的最短路径,我们就需要结合DFS。因为BFS得到的结果是一个一个分层的点,我们所能知道的只有起点到达某个状态需要几步,

具体地,我们可以先用BFS确定最短路径的长度,然后用DFS找到所有路径。我们还可以利用BFS的结果进行优化: 1. 从 end 开始做 BFS 找 start,记录沿途各点到 end 的距离,找到 start 就可以停止。 2. 将其他点与 end 的距离都标记为无穷。 3. 当我们DFS的时候,首先只选择有距离记录的相邻点开始,并且每次都只选择更近的点继续DFS,这样可以避免很多没有必要的搜索。当步数超过最短步数时则停止dfs。 4. 注意dfs出口的细节。

Java Code:

Python Code:

update 2018-05-23 18:16:44

C++ Code:

很长时间没有写比较复杂的搜索类题目,一些细节已经忘记了。

  1. 需要跟踪 step 数量的时候用分层 BFS 要记得加上关于 queue.size 的循环。

  2. 在图的DFS中,如果要获取全部路径,需要考虑到两条路径会在某一节点合并的问题,这种情况下就需要对 visited set 也进行 backtrack,保证下级dfs不会影响到上级对其他路径的搜索。

update 2018-06-23 22:32:38

Update, 一些思路缕清

先进行一次 BFS,利用其结果优化DFS。首先,我们选择从 end 出发 bfs 搜索 start,并将沿途经过的 word 加入一个 set 中。当开始DFS的时候,只选择在之前 BFS 时候遇到过的 word 继续搜索。这么做的理论依据是当我们从 end 出发 dfs 找到 start 时,其经过的 vertices 一定包含了所有从start出发到end的最短路径中的节点。

update 2018-09-30 16:42:30

Update, LeetCode版本,优化

利用BFS标记每个word对应的到end的距离,如果dfs时遇到某个word对应距离和记录的不相同,就可以剪枝。用这种方法也可以直接解决去重问题,所以就不再需要visited set。