力扣第127题-单词接龙

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

前言

力扣第127题 单词接龙 如下所示:

字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> ... -> sk

  • 每一对相邻的单词只差一个字母。
  • 对于 1 <= i <= k 时,每个 si 都在 wordList 中。注意, beginWord 不需要在 wordList 中。
  • sk == endWord

给你两个单词 beginWord 和 endWord 和一个字典 wordList ,返回从 beginWordendWord最短转换序列 中的 单词数目* 。如果不存在这样的转换序列,返回 0 。

示例 1:

输入: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
输出: 5
解释: 一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的长度 5。
复制代码

image.png

一、思路

这一题与上一题力扣第126题-单词接龙 II非常相似,都是通过逐个替换 beginWord 中的字符,保证替换后的字符在 wordList 中,最终新字符 beginWord'endWord 相等,求出最短的变换路径的节点个数

既然只需要求最短路径的节点个数,我们就不需要花费时间去存储具体的节点了。

当然这一题的思路关键仍旧是:构建一个有向图,求起点到重点的最短路径个数,在这里还是以示例一作为例子。因为每次只能替换一个字符,我们很容易构建一个下面的有向图?

image.png

利用 广度遍历 我们可以生成上面的这一张图,但是我们要思路一个问题:如何确保得到的是最短路径呢?

其实要解决这个问题很简单,我们只需要保证以下两点即可

  1. 当确定了替换后的下一个字符时,就将当前字符从路径中移除,防止走回头路
  2. 谁先碰到终点,谁就是最短的路径。即只要出现了 endWord 就立即返回。(因为长的路径一定是在后面才会碰到终点)

二、实现

实现代码

diff():自定义函数,用于比对两个字符串中不同字符的个数

实现代码与思路中保持一致,值得注意的是:构建图的时候,下一个节点可以从结果集合 wordList 中去取(只要与当前字符相差一个即满足)

    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        // 建立字典
        Set<String> dict = new HashSet<>(wordList);
        if (!dict.contains(endWord))
            return 0;
        Queue<String> path = new LinkedList<>();
        int level = 1;
        path.add(beginWord);

        while (!path.isEmpty()) {
            int size = path.size();
            for (int i = 0; i < size; i++) {
                // 当前字符串替换一个字符串
                String currWord = path.remove();
                if (currWord.equals(endWord)) {
                    return level;
                }
                // 遍历字典
                Iterator<String> iterator = dict.iterator();
                while (iterator.hasNext()){
                    String nextWord = iterator.next();
                    if (diff(currWord, nextWord)) {
                        path.add(nextWord);
                        iterator.remove();
                    }
                }
            }
            level++;
        }
        return 0;
    }

    // 返回不同字符个数
    public boolean diff(String a, String b){
        int count = 0;
        char[] arr1 = a.toCharArray();
        char[] arr2 = b.toCharArray();
        for (int i=0; i<arr1.length; i++)
            if (arr1[i] != arr2[i])
                count++;
        return count == 1;
    }
复制代码

测试代码

public static void main(String[] args) {
    String being = "hit";
    String end = "cog";
    List<String> list = Arrays.asList("hot","dot","dog","lot","log","cog");
    int ret = new Number127().ladderLength(being, end, list);
    System.out.println(ret);
}
复制代码

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享