127. 单词接龙

给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:

每次转换只能改变一个字母。
转换过程中的中间单词必须是字典中的单词。
说明:

如果不存在这样的转换序列,返回 0。
所有单词具有相同的长度。
所有单词只由小写字母组成。
字典中不存在重复的单词。
你可以假设 beginWord 和 endWord 是非空的,且二者不相同。
示例 1:

输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

输出: 5

解释: 一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
返回它的长度 5。
示例 2:

输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

输出: 0

解释: endWord "cog" 不在字典中,所以无法进行转换。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-ladder
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 1 public class Solution {
 2     /*
 3     1. 将字典中每个元素相邻近的单词位置存在map<String, List<Integer>中
 4     2. 定义两个集合,存储新延伸出来的层中的节点
 5     3. 每次从集合中取出元素进行下一层节点的生成
 6      */
 7     private Map<String, List<Integer>> map = null;
 8     private boolean isAdj(String s1, String s2) {
 9         if (s1.length() != s2.length())
10             return false;
11         int cnt = 0;
12         for (int i = 0; i < s1.length(); i++) {
13             if (s1.charAt(i) != s2.charAt(i)) {
14                 ++cnt;
15             }
16         }
17         return cnt == 1;
18     }
19     private void createMap(String word, List<String> wordList) {
20         List<Integer> adjs = new ArrayList<>();
21         for (int i = 0; i < wordList.size(); i++) {
22             if (isAdj(word, wordList.get(i)))
23                 adjs.add(i);
24         }
25         map.put(word, adjs);
26     }
27     public int ladderLength(String beginWord, String endWord, List<String> wordList) {
28         HashSet<String> set1 = new HashSet<>();
29         HashSet<String> set2 = new HashSet<>();
30         int step = 0;
31         // 建立map
32         map = new HashMap<>();
33         createMap(beginWord, wordList);
34         for (String s : wordList){
35             createMap(s, wordList);
36         }
37         set1.add(beginWord);
38         set2.add(endWord);
39         while (!set1.isEmpty() && !set2.isEmpty()) {
40             HashSet<String> t;
41             if (set1.size() > set2.size()){
42                 t = set1;
43                 set1 = set2;
44                 set2 = t;
45             }
46             ++step;
47             HashSet<String> q = new HashSet<>();
48             for (int i = 0; i < set1.size(); i++) {
49                 // 扩展下一层节点
50                 for (String s : set1) {
51                     List<Integer> next = map.get(s);
52                     if (next == null)
53                         return 0;
54                     for (Integer e : next) {
55                         String elem = wordList.get(e);
56                         if (set2.contains(elem))
57                             return ++step;
58                         q.add(wordList.get(e));
59                     }
60                 }
61             }
62             // 交换set1与q
63             set1 = q;
64         }
65         return 0;
66     }
67 
68     public static void main(String[] args) {
69         String[] words = {"hot","dog"};
70         List<String> wordList = new ArrayList<>(Arrays.asList(words));
71         int i = new Solution().ladderLength("hot", "dog", wordList);
72         System.out.println("i = " + i);
73     }
74 }

 

posted @ 2019-10-07 21:10  赤云封天  阅读(303)  评论(0编辑  收藏  举报