单词演变(剑指 Offer II 108)

单词演变

在字典(单词列表) wordList 中,从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列:
序列中第一个单词是 beginWord 。
序列中最后一个单词是 endWord 。
每次转换只能改变一个字母。
转换过程中的中间单词必须是字典 wordList 中的单词。
给定两个长度相同但内容不同的单词 beginWord 和 endWord 和一个字典 wordList ,找到从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0。
示例 1:
输入:beginWord = “hit”, endWord = “cog”, wordList = [“hot”,“dot”,“dog”,“lot”,“log”,“cog”]
输出:5
解释:一个最短转换序列是 “hit” -> “hot” -> “dot” -> “dog” -> “cog”, 返回它的长度 5。

这里使用的是BFS(这种方式其实不够高效,但是我觉得最好理解)
具体的思路:首先先决条件无非就是判断wordList 是否含有endWord ,没有的话可以直接返回了。
然后就是判断endWord 和beginWord 是否相同,相同的话皆大欢喜。
下来就是建立一个队列,一般BFS的做法都是使用队列来实现,将beginWord 存放的队列中,同时,再创建一个set集合用于记录单词是否已经入队。
然后每次将这一层的单词取出来,查找他的nextWord集合,判断集合中元素是否满足等于endWord,满足即可返回结果,否则将这个集合放在下一层中。

	public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        if (beginWord.equals(endWord)) return 0;

        Set<String> set = new HashSet<>(wordList);
        Queue<String> queue = new LinkedList<>();
        if (!set.contains(endWord)) return 0;

        Set<String> visit = new HashSet<>();
        queue.offer(beginWord);
        visit.add(beginWord);
        int step = 1;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                String str = queue.poll();
                for (String nextWord : next(str, wordList, visit)) {
                    if (nextWord.equals(endWord)) return step + 1;
                    visit.add(nextWord);
                    queue.offer(nextWord);
                }
            }
            step++;
        }

        return 0;
    }

    public List<String> next(String str, List<String> wordList, Set<String> visit) {
        List<String> list = new ArrayList<>();
        for (String word : wordList) {
            if (!visit.contains(word) && isNext(str, word)) {
                list.add(word);
            }
        }
        return list;
    }

    public boolean isNext(String str1, String str2) {
        if (str1.length() != str2.length()) return false;
        int count = 0;
        for (int i = 0; i < str1.length(); i++) {
            if (str1.charAt(i) != str2.charAt(i)) {
                count++;
            }
            if (count > 1) return false;
        }
        return count <= 1;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值