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 class Solution {
 2 
 3     public int ladderLength(String start, String end, Set<String> dict) {
 4         if (diff(start, end) == 0) return 1;
 5         if (diff(start, end) == 1) return 2;
 6         
 7         ArrayList<String> inner = new ArrayList<String>();
 8         ArrayList<String> outer = new ArrayList<String>();
 9         inner.add(start);
10         int counter = 1;
11         while (inner.size() != 0) {
12             counter++;
13             if (dict.size() == 0) return 0;
14             for (int i = 0; i < inner.size(); i++) {
15                 ArrayList<String> dicts = new ArrayList<String>(dict);
16                 for (int j = 0; j < dicts.size(); j++) {
17                     if (diff(inner.get(i), dicts.get(j)) == 1) {
18                         outer.add(dicts.get(j));
19                         dict.remove(dicts.get(j));
20                     }
21                 }
22             }
23 
24             for (int k = 0; k < outer.size(); k++) {
25                 if (diff(outer.get(k), end) <= 1) {
26                     return counter + 1;
27                 }
28             }
29 
30             ArrayList<String> temp = inner;
31             inner = outer;
32             outer = temp;
33             outer.clear();
34         }
35         return 0;
36     }
37 
38     private int diff(String start, String end) {
39         int total = 0;
40         for (int i = 0; i < start.length(); i++) {
41             if (start.charAt(i) != end.charAt(i)) {
42                 total++;
43             }
44         }
45         return total;
46     }
47 }

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

 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)) {
 5             return 0;
 6         }
 7         Queue<Node> queue = new LinkedList<>();
 8         queue.add(new Node(begin, 1));
 9 
10         while (queue.size() != 0) {
11             Node current = queue.poll();
12             String word = current.word;
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 (set.contains(tempStr)) {
20                         if (tempStr.equals(end)) {
21                             return current.depth + 1; // we find it
22                         } else {
23                             set.remove(tempStr);
24                             queue.offer(new Node(tempStr, current.depth + 1));
25                         }
26                     }
27                 }
28                 chs[i] = ch;
29             }
30         }
31         return 0;
32     }
33 }
34 
35 class Node {
36     String word;
37     int depth;
38     
39     public Node(String word, int depth) {
40         this.word = word;
41         this.depth = depth;
42     }
43 }

 

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

 

转载于:https://www.cnblogs.com/beiyeqingteng/p/5679915.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值