class Solution {
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        HashSet<String> wordSet = new HashSet<>(wordList); //替换掉题目中List结构,加速查找
        if (!wordSet.contains(endWord)) return 0; //如果目标顶点不在图中,直接返回0
        HashMap<String, Integer> map = new HashMap<>(); //用来存储已访问的节点,并存储其在路径上的位置,相当于BFS算法中的isVisted功能
        Queue<String> q = new LinkedList<>(); //构建队列,实现广度优先遍历
        q.add(beginWord); //加入源顶点
        map.put(beginWord, 1); //添加源顶点为“已访问”,并记录它在路径的位置
        while (!q.isEmpty()) { //开始遍历队列中的顶点
            String word = q.poll(); //记录现在正在处理的顶点
            int level = map.get(word); //记录现在路径的长度
            for (int i = 0; i < word.length(); i++) {
                char[] wordLetter = word.toCharArray();
                for (char j = 'a'; j <= 'z'; j++) {
                    if (wordLetter[i] == j) continue; 
                    wordLetter[i] = j; //对于每一位字母,分别替换成另外25个字母
                    String check = new String(wordLetter);
                    if (check.equals(endWord)) return map.get(word) + 1; //如果已经抵达目标节点,返回当前路径长度+1
                    if (wordSet.contains(check) && !map.containsKey(check)) { //如果字典中存在邻接节点,且这个邻接节点还未被访问
                        map.put(check, level + 1); //标记这个邻接节点为已访问,记录其在路径上的位置
                        q.add(check); //加入队列,以供广度搜索
                    }
                }
            }
        }
        return 0;
    }
}

数据结构:
HashSet<String> wordSet 实用hash存储第三个参数单词字典,加速查找

HashMap<String, Integer> map 存储已经访问过的节点,相当于visited

LinkedList<Object> q 主循环判断的Stack

算法流程:
q中添加源单词,同时在map中添加此单词,表示已占用
循环q
  取出q中的栈顶的值(poll) -> word (map中仍然占用)
  查询栈的深度 -> level
  循环word中每一个字符
    找到一个合理的匹配 ->check
    判断check是否是目标单词
      是:返回 level + 1
      不是:将check加入q,并在map中锁定check
循环完毕,所有在单词列表中的词都被锁定,无法添加进入q,则返回0,表示未找到

 

补充一个python的实现:

 1 class Solution:
 2     def ladderLength(self, beginWord: str, endWord: str, wordList: 'List[str]') -> int:
 3         wordset = set(wordList)
 4         if endWord not in wordset:
 5             return 0
 6         alpher = ['a','b','c','d','e','f','g',
 7         'h','i','j','k','l','m','n',
 8         'o','p','q','r','s','t',
 9         'u','v','w','x','y','z']
10         wordmap = {}
11         q = []
12         q.append(beginWord)
13         wordmap[beginWord] = 1
14         while len(q) > 0:
15             n = len(q)
16             temp = []
17             while n > 0:
18                 n -= 1
19                 word = q.pop()
20                 level = wordmap[word]
21                 for i in range(len(word)):
22                     for j in range(len(alpher)):
23                         if word[i] == alpher[j]:
24                             continue
25                         check = word[:i] + alpher[j] + word[i+1:]
26                         if check == endWord:
27                             return level + 1
28                             #minLength = min(minLength,level + 1)
29                         if check in wordset and check not in wordmap:
30                             wordmap[check] = level + 1
31                             temp.append(check)
32             if len(temp) > 0:
33                 q = temp[:]
34         return 0

注意加粗部分的代码,与java的语法是有区别,主要是判断q是否为空。

posted on 2018-10-21 20:55  Sempron2800+  阅读(153)  评论(0编辑  收藏  举报