码迷,mamicode.com
首页 > 其他好文 > 详细

LeetCode 126. 单词接龙 II

时间:2020-06-08 12:24:02      阅读:38      评论:0      收藏:0      [点我收藏+]

标签:ring   字符   定位   ons   单词   直接   数字   转换   void   

题目描述:

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

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

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

 

class Solution {
  public:
    //两个word能否一步转换
    bool isConnected(const string &a, const string &b) {
        int res = 0;
        for (int i = 0; i < a.size(); ++i) {
            if (a[i] != b[i])
                res++;
        }
        return res == 1;
    }

    //将数字序列转换成字符串序列
    void numToString(vector<vector<string>> &res, const vector<int> &nowSeq,
                     const string &beginWord, const string &endWord,
                     const vector<string> &wordList) {
        vector<string> temp;
        temp.push_back(beginWord);
        for (int i : nowSeq) {
            temp.push_back(wordList[i]);
        }
        temp.push_back(endWord);
        res.push_back(temp);
    }

    vector<vector<string>> findLadders(string beginWord, string endWord,
                                       vector<string> &wordList) {
        vector<vector<string>> res;

        //定位目标单词
        int endnum = 0;
        for(;endnum<wordList.size();endnum++){
            if(wordList[endnum] == endWord)break;
        }

        //没有目标单词就返回空
        if (endnum == wordList.size())
            return res;

        //排除能直接连的可能
        if (isConnected(beginWord, endWord)) {
            auto temp = vector<string>{beginWord, endWord};
            res.push_back(temp);
            return res;
        }

        //队列
        queue<vector<int>> q;

        //用cost记录到每一点的最少步数
        vector<int> cost(wordList.size(), INT_MAX);

        //把和初始单词相连接的单词都压入队列
        for (int i = 0; i < wordList.size(); i++) {
            if (isConnected(beginWord, wordList[i])) {
                q.push(vector<int>{i});
                cost[i] = 0;
            }
        }

        //构造图
        vector<vector<int>> wordMap(wordList.size(), vector<int>{});
        for (int i = 0; i < wordList.size(); ++i) {
            for (int j = i + 1; j < wordList.size(); ++j) {
                if (isConnected(wordList[i], wordList[j])) {
                    wordMap[i].push_back(j);
                    wordMap[j].push_back(i);
                }
            }
        }

        //开始搜索
        while (!q.empty()) {
            //取出q中第一个元素
            vector<int> nowSeq = q.front();
            q.pop();

            //遍历该点直接连接的点
            for (int nextNum : wordMap[nowSeq.back()]) {
                if (nextNum == endnum) {
                    if (nowSeq.size() <= cost[endnum]) {

                        //本次的步数更少,之前的结果要删除
                        if (nowSeq.size() < cost[endnum]) {
                            res.clear();
                            cost[endnum] = nowSeq.size();
                        }

                        //将当前序列加入结果
                        numToString(res, nowSeq, beginWord, endWord, wordList);
                    }
                } else {
                    //将新的序列压入队列q
                    if(nowSeq.size() <= cost[nextNum]) {
                        cost[nextNum] = nowSeq.size();
                        vector<int> temp = nowSeq;
                        temp.push_back(nextNum);
                        q.push(temp);
                    }
                }
            }
        }

        return res;
    }
};

 

LeetCode 126. 单词接龙 II

标签:ring   字符   定位   ons   单词   直接   数字   转换   void   

原文地址:https://www.cnblogs.com/airfy/p/13064813.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!