leetcode 126 单词接龙2

本文深入探讨了如何寻找两个单词间最短转换序列的算法,通过改变一个字母并确保每步转换后的单词都在字典中。文章详细介绍了使用图论和广度优先搜索(BFS)方法来解决这一问题,包括构建图、执行BFS搜索和回溯查找所有可能的最短路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

说明:

  • 如果不存在这样的转换序列,返回一个空列表。
  • 所有单词具有相同的长度。
  • 所有单词只由小写字母组成。
  • 字典中不存在重复的单词。
  • 你可以假设 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" 不在字典中,所以不存在符合要求的转换序列。
class Solution {
public:
    struct Qitem{
        string node;
        int parent_pos;
        int step;
        Qitem(string node,int parent_pos,int step):
        node(node),parent_pos(parent_pos),step(step){
        }
    };
    bool calnotsame(string &beginWord, string &endWord){
        int cnt=0;
        for(int i=0;i<beginWord.length();i++){
            if(beginWord[i]!=endWord[i]){
                cnt++;
            }
        }
        return cnt==1;//只有一个字符相同才能转换,才有效
    }
    void makegraph(string &beginWord, vector<string>& wordList,map<string,vector<string>>&graph){
  
        int has_been_word=0;
        for(int i=0;i<wordList.size();i++){
            if(wordList[i]==beginWord){
                has_been_word=1;
            }
            graph[wordList[i]]=vector<string>();//初始化临接表
        }
        for(int i=0;i<wordList.size();i++){
            for(int j=i+1;j<wordList.size();j++){
                if(calnotsame(wordList[i],wordList[j])){
                    graph[wordList[i]].push_back(wordList[j]);//互相都能访问,双向存储
                    graph[wordList[j]].push_back(wordList[i]);
                }
            }
        
        if(has_been_word==0&&calnotsame(beginWord,wordList[i])){
            graph[beginWord].push_back(wordList[i]);
        }
        }
    }
    void BFS(string beginWord, string endWord, vector<string>& wordList,map<string,vector<string>>&graph,vector<Qitem>&Q,vector<int>&end_word_pos){
        map<string,int>visit;
        int min=0;
        int front=0;
        visit[beginWord]=1;
        Q.push_back(Qitem(beginWord.c_str(),-1,1));
        while(front!=Q.size()){
            const string &node=Q[front].node;
            int step=Q[front].step;
            if(min!=0&&step>min)
                break;
            if(node==endWord){
                min=step;
                end_word_pos.push_back(front);
            }
            const vector<string>&neighbors=graph[node];
            for(int i=0;i<neighbors.size();i++){
 if(visit.find(neighbors[i])==visit.end()||visit[neighbors[i]]==step+1){//如果临接这个string没被搜索过
                Q.push_back(Qitem(neighbors[i],front,step+1));//加进队列
                visit[neighbors[i]]=step+1;//加进visit
            }
        }
            front++;
        }
    }

    vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
        map<string,vector<string>>graph;
        makegraph(beginWord, wordList,graph);
        vector<Qitem>Q;
        vector<int>end_word_pos;
        BFS(beginWord, endWord, wordList,graph,Q,end_word_pos);
        vector<vector<string>>result;
        for(int i=0;i<end_word_pos.size();i++){
            int pos=end_word_pos[i];
            vector<string>path;
            while(pos!=-1){
                path.push_back(Q[pos].node);
                pos=Q[pos].parent_pos;
            }
            result.push_back(vector<string>());
            for(int j=path.size()-1;j>=0;j--){
                result[i].push_back(path[j]);
            }
        }
        return result;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值