欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

126. 单词接龙 II

程序员文章站 2022-05-20 14:05:44
...

给定两个单词(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”]
]
https://blog.csdn.net/Bendaai/article/details/80951542
https://blog.csdn.net/qq_17550379/article/details/83652490
我的代码 超时

static int y=[]()
{
    std::ios::sync_with_stdio(false);
    cin.tie(NULL);
    return 0;
}();
vector<vector<int>> v_e;
vector<vector<string>> v_solution;
vector<int> x;
string bWord;
string eWord;
int n;
int min_len;
int compare(string endWord,string wordLi)
{
    int num=0;
    for(int i=0;i<endWord.length();i++)
    {
        if(endWord[i]!=wordLi[i])
            num++;
    }
    return num;
}
bool isok(string nWord,vector<string>& words)
{
    for(int i=0;i<x.size();i++)
        if(nWord==words[x[i]]) return false;
    if(nWord==bWord) return false;
    return true;
}
void dfs(int t,string nowWord,vector<string>& words,int len)
{
    if(len+t>min_len) return;
    if(t==0)
    {
        if(min_len>len)
            min_len=len;
        vector<string> temp;
        temp.push_back(bWord);
        for(int i=0;i<x.size();i++)
            temp.push_back(words[x[i]]);
        v_solution.push_back(temp);
        return ;
    }
    else
    {
        for(int i=0;i<v_e[t-1].size();i++)
        {
            if(compare(nowWord,words[v_e[t-1][i]])==1)
            {
                x.push_back(v_e[t-1][i]);
                dfs(t-1,words[v_e[t-1][i]],words,len+1);
                x.pop_back();
            }
            
        }
        if(min_len==n+1) return;
        if(len+t+1>min_len) return;
            for(int i=0;i<v_e[t].size();i++)
            {
                 if(compare(nowWord,words[v_e[t][i]])==1&&isok(words[v_e[t][i]],words))
                 {
                       x.push_back(v_e[t][i]);
                       dfs(t,words[v_e[t][i]],words,len+1);
                       x.pop_back();
                 }
            }
    }
    return;
}
class Solution {
public:
    vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
        bWord=beginWord;
        min_len=wordList.size();
        eWord=endWord;
        int len=beginWord.size();
        n=compare(endWord,beginWord);
        vector<vector<string>>().swap(v_solution);
        vector<int>().swap(x);
        vector<vector<int>>().swap(v_e); 
        v_e.resize(len+1);
        vector<vector<string>> v_find;
        for(int i=0;i<wordList.size();i++)
        {
            int e=compare(endWord,wordList[i]);
            v_e[e].push_back(i);
        }
        if(v_e[0].size()==0) return v_solution;
        dfs(n,beginWord,wordList,1);
        for(int i=0;i<v_solution.size();i++)
        {
           if(v_solution[i].size()==min_len)
                v_find.push_back(v_solution[i]);
        }
        return v_find;
    }
};

最短代码 820 ms 178.6 MB

class Solution {
public:
    vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
        vector<vector<string>> res;
        unordered_set<string> dict(wordList.begin(), wordList.end());
        vector<string> p{beginWord};
        queue<vector<string>> paths;
        paths.push(p);
        int level = 1, minLevel = INT_MAX;
        unordered_set<string> words;
        while (!paths.empty()) 
        {
            auto t = paths.front(); paths.pop();
            if (t.size() > level) 
            {
                for (string w : words) dict.erase(w);
                words.clear();
                level = t.size();
                if (level > minLevel) break;
            }
            string last = t.back();
            for (int i = 0; i < last.size(); ++i) 
            {
                string newLast = last;
                for (char ch = 'a'; ch <= 'z'; ++ch) 
                {
                    newLast[i] = ch;
                    if (!dict.count(newLast)) continue;
                    words.insert(newLast);
                    vector<string> nextPath = t;
                    nextPath.push_back(newLast);
                    if (newLast == endWord) 
                    {
                        res.push_back(nextPath);
                        minLevel = level;
                    } else paths.push(nextPath);
                }
            }
        }
        return res;
    }
};

最快代码 48 ms 17.4 MB

class Solution {
public:
    vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
        int N = beginWord.size();
        vector<vector<string>> ret;
        wordList.push_back(beginWord);
        vector<unordered_set<int>> link(wordList.size());
        unordered_map<string, int> word2id;
        for (int i = 0; i < wordList.size(); ++i){
            word2id[wordList[i]] = i;
        }
        if (word2id.count(endWord) == 0) return ret;
        int startId = wordList.size() - 1;
        int endId = word2id[endWord];

        vector<bool> visited(wordList.size(), false);
        unordered_set<int> a, b;
        a.insert(startId);
        b.insert(endId);
        visited[startId] = true;
        visited[endId] = true;
        while (!a.empty() && !b.empty() && ret.empty()){
            unordered_set<int> tmp;
            if (a.size() > b.size()){
                swap(a, b);
            }
            for (int x : a){
                string w = wordList[x];
                for (int i = 0; i < N; ++i){
                    char t = w[i];
                    for (char c = 'a'; c <= 'z'; ++c){
                        w[i] = c;
                        auto it = word2id.find(w);
                        if (t == c || it == word2id.end()) continue;
                        if (b.count(it->second)){
                            build(x, it->second, link, wordList, ret);
                        }
                        else if (!visited[it->second]){
                            tmp.insert(it->second);
                            link[it->second].insert(x);
                        }
                    }
                    w[i] = t;
                }
            }
            for (int i : tmp){
                visited[i] = true;
            }
            swap(tmp, a);
        }
        return ret;
    }

    void build(int x, int y, vector<unordered_set<int>>& link, vector<string>& wordList, vector<vector<string>>& ret){
        vector<vector<int>> left, right;
        vector<int> vec = { x };
        dfs(vec, link, left);
        vec[0] = y;
        dfs(vec, link, right);
        for (auto& v1 : left){
            for (auto& v2 : right){
                ret.push_back({});
                vector<string>& r = ret.back();
                for (int i = v1.size() - 1; i >= 0; --i){
                    r.push_back(wordList[v1[i]]);
                }
                for (int i = 0; i < v2.size(); ++i){
                    r.push_back(wordList[v2[i]]);
                }
                if (v1.back() != wordList.size() - 1){
                    reverse(r.begin(), r.end());
                }
            }
        }
    }
    void dfs(vector<int>& vec, vector<unordered_set<int>>& link, vector<vector<int>>& ret){
        int i = vec.back();
        if (link[i].empty()){
            ret.push_back(vec);
        }
        else{
            for (int j : link[i]){
                vec.push_back(j);
                dfs(vec, link, ret);
                vec.pop_back();
            }
        }
    }
};
相关标签: 领扣