Word Ladder II 解答

本文探讨了如何从一个单词转换到另一个单词的最短路径问题,涉及算法优化和数据结构应用,通过实例展示了实现过程。

Question

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:

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

For example,

Given:
beginWord = "hit"
endWord = "cog"
wordList = ["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.

Solution

Two major diffrences compared with "Word Ladder"

1. We should record path, i.e previous nodes

2. Only when stepNums changes can we remove this node from wordDict

注意的点有三个:

1. Queue中的数据结构

2. 什么时候判断不再遍历这个点?

当这个点已经在之前的层中被遍历(即当前步数大于之前的步数)=>需要一个Map来记录最少的步数

3. 什么时候判断不再遍历最后值为end的点?=>设置一个变量,记录第一个遍历到end值的步数。之后再遍历到end值,步数要与其比较。

 1 class WordNode {
 2     public String word;
 3     public WordNode prev;
 4     public int level;
 5     public WordNode (String word, WordNode prev, int level) {
 6         this.word = word;
 7         this.prev = prev;
 8         this.level = level;
 9     }
10 }
11 
12 public class Solution {
13     /**
14       * @param start, a string
15       * @param end, a string
16       * @param dict, a set of string
17       * @return a list of lists of string
18       */
19     public List<List<String>> findLadders(String start, String end, Set<String> dict) {
20         // write your code here
21         List<List<String>> result = new ArrayList<>();
22         if (dict == null) {
23             return result;
24         }
25         dict.add(start);
26         dict.add(end);
27         // get adjacent list
28         Map<String, Set<String>> adjacentList = getNeighbors(dict);
29         Map<String, Integer> visited = new HashMap<>();
30         int prevLevel = 0;
31         Queue<WordNode> queue = new ArrayDeque<>();
32         queue.offer(new WordNode(start, null, 1));
33         // bfs
34         while (!queue.isEmpty()) {
35             WordNode cur = queue.poll();
36             if (end.equals(cur.word)) {
37                 if (prevLevel == 0 || cur.level == prevLevel) {
38                     prevLevel = cur.level;
39                     addRecordToResult(result, cur);
40                 } else {
41                     break;
42                 }
43             } else {
44                 Set<String> neighbors = adjacentList.get(cur.word);
45                 if (neighbors == null || neighbors.size() == 0) {
46                     continue;
47                 }
48                 Set<String> removeSet = new HashSet<>();
49                 for (String str : neighbors) {
50                     if (visited.containsKey(str)) {
51                         int visitedLevel = visited.get(str);
52                         if (cur.level + 1 > visitedLevel) {
53                             removeSet.add(str);
54                             continue;
55                         }
56                     }
57                     visited.put(str, cur.level + 1);
58                     queue.offer(new WordNode(str, cur, cur.level + 1));
59                 }
60                 neighbors.removeAll(removeSet);
61             }
62         }
63         return result;
64     }
65     
66     private Map<String, Set<String>> getNeighbors(Set<String> dict) {
67         Map<String, Set<String>> map = new HashMap<>();
68         for (String str : dict) {
69             map.put(str, new HashSet<String>());
70             char[] arr = str.toCharArray();
71             int len = arr.length;
72             for (int i = 0; i < len; i++) {
73                 char prev = arr[i];
74                 for (char j = 'a'; j <= 'z'; j++) {
75                     if (prev == j) {
76                         continue;
77                     }
78                     arr[i] = j;
79                     String newStr = new String(arr);
80                     if (dict.contains(newStr)) {
81                         map.get(str).add(newStr);
82                     }
83                 }
84                 arr[i] = prev;
85             }
86         }
87         return map;
88     }
89     
90     private void addRecordToResult(List<List<String>> result, WordNode end) {
91         List<String> record = new ArrayList<>();
92         while (end != null) {
93             record.add(end.word);
94             end = end.prev;
95         }
96         Collections.reverse(record);
97         result.add(record);
98     }
99 }

 

转载于:https://www.cnblogs.com/ireneyanglan/p/4868428.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值