zoukankan      html  css  js  c++  java
  • 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"
    "cog"
    ["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"
    "cog"
    ["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();
            }
        }
    };
    联系方式:emhhbmdfbGlhbmcxOTkxQDEyNi5jb20=
  • 相关阅读:
    设计模式20-观察者模式
    设计模式19-备忘录模式
    设计模式18-中介者模式
    设计模式17-迭代器模式
    设计模式16-解释器模式
    Wireshark基本介绍和学习TCP三次握手
    Jmeter CSV 参数化/检查点/断言
    Jmeter运营活动并发测试—巧用集合点
    一个简单的性能测试
    Jmeter对HTTP请求压力测试、并发测试
  • 原文地址:https://www.cnblogs.com/zl1991/p/14686125.html
Copyright © 2011-2022 走看看