Leetcode 126 127 单词接龙i&ii

i:

/*
 * @lc app=leetcode.cn id=127 lang=cpp
 *
 * [127] 单词接龙
 *
 * https://leetcode-cn.com/problems/word-ladder/description/
 *
 * algorithms
 * Hard (45.95%)
 * Likes:    738
 * Dislikes: 0
 * Total Accepted:    104.9K
 * Total Submissions: 226.9K
 * Testcase Example:  '"hit"\n"cog"\n["hot","dot","dog","lot","log","cog"]'
 *
 * 字典 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。
 * 
 * 
 * 示例 2:
 * 
 * 
 * 输入:beginWord = "hit", endWord = "cog", wordList =
 * ["hot","dot","dog","lot","log"]
 * 输出:0
 * 解释:endWord "cog" 不在字典中,所以无法进行转换。
 * 
 * 
 * 
 * 提示:
 * 
 * 
 * 1 
 * endWord.length == beginWord.length
 * 1 
 * wordList[i].length == beginWord.length
 * beginWord、endWord 和 wordList[i] 由小写英文字母组成
 * beginWord != endWord
 * wordList 中的所有字符串 互不相同
 * 
 * 
 */

输出最短路径长度,可以使用bfs的思路,使用queue来记录当前step的所有单词,然后对每个单词遍历长度及a-z,如果处于dict中则塞入队列并从dict中删除,记得beginWord也算1

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        int step=0;
        set<string> m;
        for(string s:wordList){
            m.insert(s);
        }
        if(m.count(endWord)==0)
            return 0;
        queue<string> q;
        q.push(beginWord);
        int l=beginWord.size();
        while(!q.empty()&&!m.empty()){
            step++;
            int len=q.size();
            for(int i=0;i<len;++i){
                string word=q.front();
                q.pop();
                for(int j=0;j<l;++j){
                    char ch=word[j];
                    for(int k='a';k<='z';++k){
                        if(k==ch)
                            continue;
                        word[j]=k;
                        if(word==endWord)
                            return step+1;
                        if(m.count(word)!=0)
                        {
                            m.erase(word);
                            q.push(word);
                        }
                    }
                    word[j]=ch;
                }
            }
        }
        return 0;
    }
};

ii

/*
 * @lc app=leetcode.cn id=126 lang=cpp
 *
 * [126] 单词接龙 II
 *
 * https://leetcode-cn.com/problems/word-ladder-ii/description/
 *
 * algorithms
 * Hard (39.17%)
 * Likes:    422
 * Dislikes: 0
 * Total Accepted:    31K
 * Total Submissions: 80.6K
 * Testcase Example:  '"hit"\n"cog"\n["hot","dot","dog","lot","log","cog"]'
 *
 * 给定两个单词(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" 不在字典中,所以不存在符合要求的转换序列。
 * 
 */

需要记录所有最短路径的单词

这里记录路径的时候使用path[parent] vertor,来记录parent的所有后续单词。记录时使用bfs,然后输出路径的时候使用dfs。

这里需要注意,不能使用queue来进行bfs遍历,因为如果parent1的后续中有endWord的话,parent2的后续也有endWord,但是此时dict已经删除了endWord,会使得parent2无法被记录。因此使用unordered_set current ,next来记录当前以及下一步的单词,在记录完成路径后从dict中删除之前的next

class Solution {
public:
    vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
        unordered_set<string> dict(wordList.begin(), wordList.end()),cur,next;
        if(dict.find(endWord)==dict.end())
            return {};
        vector<vector<string>> ladders;
        vector<string> ladder;
        ladder.push_back(beginWord);
        unordered_map<string, vector<string>> path;
        int l=beginWord.size();
        cur.insert(beginWord);
        while(true){
            for(string s:cur){
                dict.erase(s);
            }
            for(string s:cur){
                string parent=s;
                for(int i=0;i<l;++i){
                    char ch=s[i];
                    for(char j='a';j<='z';++j){
                        s[i]=j;
                        if(dict.find(s)!=dict.end()){
                            path[parent].push_back(s);
                            next.insert(s);
                        }
                    }
                    s[i]=ch;
                }
            }
            if(next.empty()) break;
            if(next.find(endWord)!=next.end()){
                genLadders(beginWord,endWord,ladders,ladder,path);
                return ladders;
            }
            cur.clear();
            swap(cur,next);
        }
        return ladders;
    }
    void genLadders(string beginWord, string endWord, vector<vector<string>>& ladders, vector<string> &ladder,unordered_map<string, vector<string>>& path){
        if(beginWord==endWord){
            ladders.push_back(ladder);
            return;
        }
        for(int i=0;i<path[beginWord].size();++i){
            string word=path[beginWord][i];
            ladder.push_back(word);
            genLadders(word,endWord,ladders,ladder,path);
            ladder.pop_back();
        }
    }
};

 

posted @ 2021-04-21 17:31  鸭子船长  阅读(106)  评论(0编辑  收藏  举报