126. Word Ladder I & II

Word Ladder I

Given two words (start and end), and a dictionary, find the length of shortest transformation sequence 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
 Notice
  • Return 0 if there is no such transformation sequence.
  • 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"]

As one shortest transformation is"hit" -> "hot" -> "dot" -> "dog" -> "cog", return its length 5.

分析:

BFS。

 1 public int ladderLength(String begin, String end, List<String> list) {
 2         Set<String> visited = new HashSet<>();
 3         if (!list.contains(end)) return 0;
 4         Queue<String> queue = new LinkedList<>();
 5         int level = 1;
 6         queue.add(begin);
 7         visited.add(begin);
 8         while (!queue.isEmpty()) {
 9             level++;
10             int size = queue.size();
11             for (int k = 1; k <= size; k++) {
12                 String word = queue.poll();
13                 for (String neighbor : getNeighbors(word, new HashSet<>(list))) {
14                     if (neighbor.equals(end)) return level;
15                     if (!visited.contains(neighbor)) {
16                         visited.add(neighbor);
17                         queue.offer(neighbor);
18                     }
19                 }
20             }
21         }
22         return 0;
23     }
24     
25     private List<String> getNeighbors(String word, Set<String> set) {
26         List<String> neighbors = new ArrayList<>();
27         char[] chs = word.toCharArray();
28         for (int i = 0; i < chs.length; i++) {
29             char ch = chs[i];
30             for (char temp = 'a'; temp <= 'z'; temp++) {
31                 chs[i] = temp;
32                 String neighbor = new String(chs);
33                 if (set.contains(neighbor) && !word.equals(neighbor)) {
34                     neighbors.add(neighbor);
35                 }
36             }
37             chs[i] = ch;
38         }
39         return neighbors;
40     }

 

第二种方法:递归,复杂度更高。

 1 public class Solution {
 2     public static void main(String[] args) {
 3         Set<String> set = new HashSet<String>();
 4         set.add("hot");
 5         set.add("dot");
 6         set.add("dog");
 7         set.add("lot");
 8         set.add("log");
 9 
10         Solution s = new Solution();
11         System.out.println(s.ladderLength("hit", "cog", set));
12     }
13 
14     public List<List<String>> ladderLength(String begin, String end, Set<String> set) {
15 
16         List<String> list = new ArrayList<String>();
17         List<List<String>> listAll = new ArrayList<List<String>>();
18         Set<String> used = new HashSet<String>();
19         helper(begin, end, list, listAll, used, set);
20         return listAll;
21     }
22 
23     // find out all possible solutions
24     public void helper(String current, String end, List<String> list, List<List<String>> listAll, Set<String> used,
25             Set<String> set) {
26         list.add(current);
27         used.add(current);
28 
29         if (diff(current, end) == 1) {
30             ArrayList<String> temp = new ArrayList<String>(list);
31             temp.add(end);
32             listAll.add(temp);
33         }
34 
35         for (String str : set) {
36             if (!used.contains(str) && diff(current, str) == 1) {
37                 helper(str, end, list, listAll, used, set);
38             }
39         }
40         list.remove(current);
41         used.remove(current);
42     }
43 
44     // return the # of letters difference
45     public int diff(String word1, String word2) {
46 
47         int count = 0;
48         for (int i = 0; i < word1.length(); i++) {
49             if (word1.charAt(i) != word2.charAt(i)) {
50                 count++;
51             }
52         }
53         return count;
54     }
55 }

方法3

 1 class Solution {
 2     public int ladderLength(String begin, String end, List<String> list) {
 3         Set<String> set = new HashSet<>(list);
 4         if (!set.contains(end)) return 0;
 5         Queue<String> queue = new LinkedList<>();
 6         int level = 0;
 7         queue.add(begin);
 8         while (queue.size() != 0) {
 9             level++;
10             int size = queue.size();
11             for (int k = 1; k <= size; k++) {
12                 String word = queue.poll();
13                 char[] chs = word.toCharArray();
14                 for (int i = 0; i < chs.length; i++) {
15                     char ch = chs[i];
16                     for (char temp = 'a'; temp <= 'z'; temp++) {
17                         chs[i] = temp;
18                         String tempStr = new String(chs);
19                         if (tempStr.equals(end)) return level + 1;
20                         if (set.contains(tempStr)) {
21                             set.remove(tempStr);
22                             queue.offer(tempStr);
23                         }
24                     }
25                     chs[i] = ch;
26                 }
27             }
28         }
29         return 0;
30     }
31 }

 

Word Ladder II

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", and dict = ["hot","dot","dog","lot","log"], return:

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

分析:

原理同上,按照层进行递进,当最外层到达end以后,我们就退出。

 1 class Solution {
 2     public List<List<String>> findLadders(String start, String end, List<String> dictList) {
 3         List<List<String>> result = new ArrayList<>();
 4         boolean hasFound = false;
 5         Set<String> dict = new HashSet<>(dictList);
 6         Set<String> visited = new HashSet<>();
 7         if (!dict.contains(end)) {
 8             return result;
 9         }
10         Queue<Node> candidates = new LinkedList<>();
11         candidates.offer(new Node(start, null));
12         while (!candidates.isEmpty()) {
13             int count = candidates.size();
14             if (hasFound) return result;
15             for (int k = 1; k <= count; k++) {
16                 Node node = candidates.poll();
17                 String word = node.word;
18                 char[] chs = word.toCharArray();
19                 for (int i = 0; i < chs.length; i++) {
20                     char temp = chs[i];
21                     for (char ch = 'a'; ch <= 'z'; ch++) {
22                         chs[i] = ch;
23                         String newStr = new String(chs);
24                         if (dict.contains(newStr)) {
25                             visited.add(newStr);
26                             Node newNode = new Node(newStr, node);
27                             candidates.add(newNode);
28                             if (newStr.equals(end)) {
29                                 hasFound = true;
30                                 List<String> path = getPath(newNode);
31                                 result.add(path);
32                             }
33                         }
34                     }
35                     chs[i] = temp;
36                 }
37             }
38             dict.removeAll(visited);
39         }
40         return result;
41     }
42 
43     private List<String> getPath(Node node) {
44         List<String> list = new LinkedList<>();
45         while (node != null) {
46             list.add(0, node.word);
47             node = node.pre;
48         }
49         return list;
50     }
51 }
52 
53 class Node {
54     String word;
55     Node pre;
56 
57     public Node(String word, Node pre) {
58         this.word = word;
59         this.pre = pre;
60     }
61 }

 

posted @ 2016-07-18 07:03  北叶青藤  阅读(360)  评论(0编辑  收藏  举报