leetcode127 - 单词接龙(待完善,目前只实现了单向广度搜索)

介绍

标签:广度搜索
建议使用双向广度搜索并优化图遍历

leetcode57 - 插入区间
难度 中等

单词接龙
https://leetcode-cn.com/problems/word-ladder/

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

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

说明:

  • 如果不存在这样的转换序列,返回 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” 不在字典中,所以无法进行转换。



解题思路

朴素主义写法:

在这种情况下去寻找只改变一个字母的下一个单词,与其去遍历数组,还不如将每一位替换来得快,尤其是在传入大量数据的时候

  1. 建立队列,用于后面的广度搜索,并将初始元素入队。
  2. 建立哈希映射,用于记录那个单词是否被访问过,同时保存对应的路径长
  3. 开始广度搜索,遍历每个单词
  4. 在当前单词遍历每一位的字母,同时在将其替换为a-z的每一个字母进行尝试
  5. 当发现能匹配目标单词的时候直接输出当前保存的路径+1
  6. 当发现能匹配数组中的单词时,入队,并将当前路径+1存入哈希映射
  7. 其他情况不管,继续遍历
  8. 当全部遍历了一遍时,直接return 0,查找失败




代码

class Solution {
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        //首先将数组转换为哈希表提高效率
        HashSet<String> wordSet = new HashSet<>(wordList);
        //判断出特殊情况
        if (wordSet.size() == 0 || !wordSet.contains(endWord))
            return 0;

        //广度搜索使用的队列
        Queue<String> queue = new LinkedList<>();
        queue.offer(beginWord);//将第一个单词入队

        //记录每个单词对应路径长度
        Map<String, Integer> map = new HashMap<>();
        map.put(beginWord, 1);

        //用while进行广度搜索
        while (!queue.isEmpty()) {
            //取出对首元素,开始判断
            String word = queue.poll();
            int path  = map.get(word); //获取到该单词的路径长度

            //遍历每个字符尝试替换
            for (int i = 0; i < word.length(); i++) {
                // //将单词从String转换为char array,用于替换
                char[] chars = word.toCharArray();
                //将当前为字符替换为a-k,全部试一次
                for (char k = 'a'; k <= 'z'; k++) {
                    chars[i] = k;
                    String newWord = String.valueOf(chars);
                    //当遍历到结尾的时候,直接返回当前长度+1
                    if (newWord.equals(endWord)) {
                        return path + 1;
                    }
                    //发现改变之后的单词在传入的单词列表中,并且没有访问过时
                    if (wordSet.contains(newWord) && !map.containsKey(newWord)) {
                        //记录长度
                        map.put(newWord, path + 1);
                        //加入队尾,准备下一轮的遍历
                        queue.offer(newWord);
                    }
                }
            }
        }
        return 0;
    }
}

你可能感兴趣的:(LeetCode,算法,leetcode,java,bfs,数据结构)