Word Ladder II Graph

单词转换路径算法
本文介绍了一种算法,该算法能够找到两个单词之间的最短转换路径,每次只改变一个字母,并确保每个中间单词都在给定的字典中。通过使用广度优先搜索(BFS)建立图结构,并利用深度优先搜索(DFS)来寻找从终点到起点的所有路径。

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

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

For example,

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

Return

  [
    ["hit","hot","dot","dog","cog"],
    ["hit","hot","lot","log","cog"]
  ]

 

Note:

  • All words have the same length.
  • All words contain only lowercase alphabetic characters.

The solution contains two steps 1 Use BFS to construct a graph. 2. Use DFS to construct the paths from end to start.Both solutions got AC within 1s.

The first step BFS is quite important. I summarized three tricks

1) Using a MAP to store the min ladder of each word, or use a SET to store the words visited in current ladder, when the current ladder was completed, delete the visited words from unvisited. That's why I have two similar solutions.

2) Use Character iteration to find all possible paths. Do not compare one word to all the other words and check if they only differ by one character.

3) One word is allowed to be inserted into the queue only ONCE. See my comments.

 

The idea is to use bfs build the graph level by level, use Map<String,Set> to store the parents of string, then use dfs to find the path.

 

 1 public class Solution {
 2     List<List<String>> result;
 3     HashMap<String, Set<String>> wordGraph;
 4     public List<List<String>> findLadders(String start, String end, Set<String> dict) {
 5         result = new ArrayList<List<String>>();
 6         if(dict == null || dict.size() == 0) return result;
 7         wordGraph = new HashMap<String, Set<String>>();
 8         wordGraph.put(start, new HashSet<String>());
 9         LinkedList<String> queue = new LinkedList<String>();
10         HashSet<String> used = new HashSet<String>();
11         queue.add(start);
12         queue.add(null);
13         boolean flg = false;
14         while(queue.size() != 1){
15             String cur = queue.poll();
16             used.add(cur);
17             if(cur == null){
18                 if(flg == true) break;
19                 else queue.add(null);
20             }else{
21                 char[] arr = cur.toCharArray();
22                 for(int i = 0; i < cur.length(); i ++){
23                     for(char j = 'a'; j <= 'z'; j ++){
24                         if(arr[i] == j) continue;
25                         char tmp = arr[i];
26                         arr[i] = j;
27                         String tmpString = String.valueOf(arr);
28                         if(end.equals(tmpString)){
29                             flg = true;
30                             if(!wordGraph.containsKey(tmpString)){
31                                 Set<String> parents = new HashSet<String>();
32                                 parents.add(cur);
33                                 wordGraph.put(tmpString, parents);
34                             }else{
35                                 wordGraph.get(tmpString).add(cur);
36                             }
37                         }else if(dict.contains(tmpString) && !used.contains(tmpString) && flg != true){
38                             if(!wordGraph.containsKey(tmpString)){
39                                 Set<String> parents = new HashSet<String>();
40                                 parents.add(cur);
41                                 wordGraph.put(tmpString, parents);
42                             }else{
43                                 wordGraph.get(tmpString).add(cur);
44                             }
45                             queue.add(tmpString);
46                             
47                         }
48                         arr[i] = tmp;
49                     }
50                 }
51             }
52         }
53         if(wordGraph.containsKey(end))
54             findPath(end, start, new ArrayList<String>());
55         return result;
56     }
57         
58     
59     private void findPath(String cur, String goal, ArrayList<String> row){
60         if(cur.equals(goal)){
61             row.add(0, cur);
62             result.add(row);
63         }else{
64             for(String pre : wordGraph.get(cur)){
65                 row.add(0, cur);
66                 findPath(pre, goal, new ArrayList<String>(row));
67                 row.remove(0);
68             }
69         }
70     }
71 }

 

转载于:https://www.cnblogs.com/reynold-lei/p/4401974.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值