LeetCode 126. 单词接龙 II(图的BFS)

1. 题目

给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列。

转换需遵循如下规则:

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

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

示例 1:
输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]
输出:
[
  ["hit","hot","dot","dog","cog"],
  ["hit","hot","lot","log","cog"]
]

示例 2:
输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
输出: []
解释: endWord "cog" 不在字典中,所以不存在符合要求的转换序列。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-ladder-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

类似题目:
LeetCode 127. 单词接龙(图的BFS/双向BFS)
程序员面试金典 - 面试题 17.22. 单词转换(BFS)

2. BFS解题

  • 详见注释
class Solution {
public:
    vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) 
    {
        vector<vector<string>> ans;
        unordered_set<string> wlist(wordList.begin(),wordList.end());
        unordered_set<string> words;//存放当次被加入到路径的单词
        queue<vector<string>> q;//队列里存放的是可行的路径
        q.push({beginWord});
        words.insert(beginWord);
        int level = 1, minLevel = INT_MAX, n, i;
        vector<string> frontPath, newPath;
        string lastWordOfPath, newLastWord;
        char ch;
        while(!q.empty())
        {
            n = q.size();
            while(n--)
            {
                frontPath = q.front();//vector<string>
                q.pop();//frontPath出队
                if(frontPath.size() > level)//下一个level时进入
                {
                    for(string word:words) 
                        wlist.erase(word);//将上一个lv进入路径的单词从集合中删除
                    words.clear();
                    level = frontPath.size();//level+1
                    if(level > minLevel) //如果level比最小的还大,没必要进行下去
                        break;
                }
                lastWordOfPath = frontPath.back();
                for(i = 0; i < lastWordOfPath.size(); i++)
                {   //根据最后一个单词衍生新的单词
                    newLastWord = lastWordOfPath;
                    for(ch = 'a'; ch <= 'z'; ch++)
                    {
                        newLastWord[i] = ch;
                        if(!wlist.count(newLastWord)) //新单词不在集合中,下一个
                            continue;
                        words.insert(newLastWord);//在集合中,加入路径,并记录在words
                        newPath = frontPath;//vector<string>
                        newPath.push_back(newLastWord);
                        if(newLastWord == endWord)
                        {
                            ans.push_back(newPath);
                            minLevel = level;
                        }
                        else
                            q.push(newPath);
                    }
                }
            }
        }
        return ans;
    }
};

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Michael阿明

如果可以,请点赞留言支持我哦!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值