127. 单词接龙-中等-图、BFS、字符串

127. 单词接龙-中等-图、BFS、字符串

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

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

说明:

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

示例 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" 不在字典中,所以无法进行转换。

题解

与昨天题目正相反,即便看完答案也觉得,这尼玛是中等题?

不过认真地思考和复盘还是需要的。

思路:根据单词与单词之间的转换,可以隐隐约约感觉到,这是一道关于的问题。每次变化的种类多,所以是一道BFS的问题。

此题的难点有两个:

  1. 首先是图的表示,官网的答案建立了图,而另一个比较好题解则只是用到了图的思想,但没有将图建立。所以在此题中,的思想是一个值得思考的点。
  2. 第二个难点我觉得就是BFS,感觉需要考究的细节有很多,不常用的话很容易忽略这些。
  3. 单词的变化感觉也不是很简单,可以单出一道题了,需要将String类型转换为char[]数组形式,再对每个字符进行变化。(注意保存变化之前的字符,还要还原呢)

第二次做的话尝试独自思考双BFS的方法吧

class Solution {

    Set<String> wordSet;
    Set<String> visited;
    Queue<String> queue;

    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        // 此题没有建立图,却是一道关于图的题,思想也是图的思想
        // 首先把数据存入哈希表中,
        wordSet = new HashSet<>(wordList);
        visited = new HashSet<>();  // 把遍历过的数据放入visited里
        visited.add(beginWord);
        if( wordSet.size() == 0 || !wordSet.contains(endWord)){
            return 0;
        }
        wordList.remove(beginWord);



        // BFS就需要用到队列了
        queue = new LinkedList<>();
        int step = 1;
        queue.offer(beginWord);
        while(!queue.isEmpty()){
            // 需要用qsize记录queue,不能在for里面直接调用size()函数,每次queue的size都不一样
            int qsize = queue.size();
            // 需要用for在进行二次遍历
            for(int i=0; i<qsize; i++){
                String word = queue.poll();
                if(wordDetect(word, endWord)){
                    return step + 1;
                }
            }
            step++;
        }
        return 0;
    }

    public boolean wordDetect(String word, String endWord){
        // 如何更改字符串的每个字母也是本题的难点之一
        char[] charWord = word.toCharArray();
        for(int i=0; i<charWord.length; i++ ){
            char originChar = charWord[i];
            for(char c ='a'; c <= 'z';c++){
                if(c == originChar){
                    continue;
                }
                charWord[i] = c;
                String newWord = new String(charWord);
                // 在set里面存在,且没有遍历过,直接放入队列里面
                if(wordSet.contains(newWord) && !visited.contains(newWord)){
                    if(newWord.equals(endWord)){
                        return true;
                    }else{
                        visited.add(newWord);
                        queue.add(newWord);
                    }
                }
            }
            charWord[i] = originChar;
        }
        return false;
        
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值