单词接龙II

原题在这里

  概述题意,相比于I,这里多了要求出输出所有最短路径。

analyse:

  1.在队列元素里增添一个vector<string>属性即可

code:

复制代码
class Solution
{
    struct iis
    {
        int x;
        int y;
        vector<string> s;
        friend bool operator<(iis a, iis b)
        {
            return a.y > b.y;
        }
    };

public:
    vector<vector<string>> findLadders(string beginWord, string endWord, vector<string> &wordList)
    {
        map<pair<int, string>, int> mp;
        vector<vector<int>> num(1, vector<int>()); //存入wordlist下标
        int pd = -1, id = 0, step = 1, n = wordList.size();
        for (int i = 0; i < wordList.size(); ++i)
            if (wordList[i] == beginWord)
                pd = i;
        if (pd == -1)
            pd = n++, wordList.emplace_back(beginWord); //初始点也需要处理
        vector<int> vis(n);
        for (int i = 0; i < n; ++i)
        {
            string s = wordList[i];
            for (int j = 0; j < s.length(); ++j)
            {
                string x = s;
                x.erase(x.begin() + j);
                if (!mp[{j, x}])
                {
                    mp[{j, x}] = ++id;
                    num.emplace_back(vector<int>(1, i));
                }
                else
                    num[mp[{j, x}]].emplace_back(i);
            }
        }
        priority_queue<iis> q;
        vector<vector<string>> ans;
        q.push({pd, 1, vector<string>(1, beginWord)});
        while (q.size())
        {
            iis now = q.top();
            q.pop();
            if (wordList[now.x] == endWord)
            {
                if (step == 1)
                    step = now.y;
                if (now.y > step)
                    break;
                ans.emplace_back(now.s);
                continue;
            }
            vis[now.x] = now.y;
            string s = wordList[now.x];
            for (int i = 0; i < s.length(); ++i)
            {
                string x = s;
                x.erase(x.begin() + i);
                for (int j = 0; j < num[mp[{i, x}]].size(); ++j)
                {
                    int y = num[mp[{i, x}]][j];
                    if (!vis[y])
                    {
                        iis tmp{y, now.y + 1, now.s};
                        tmp.s.emplace_back(wordList[y]);
                        q.push(tmp);
                    }
                }
            }
        }
        return ans;
    }
};
习惯性多写了没必要的优先队列,这里使用队列+记忆化bfs就行了
复制代码

  2.优化:普通队列+记忆化bfs遍历+队列元素优化(vector<string>写成string,最后将可用string转存为vector<string>)

    优化结果:时间复杂度为原来1/4,空间复杂度为原来1/5。

code:

复制代码
class Solution
{
    struct iis
    {
        int x;
        string s;
    };
    vector<string> tos(string s)
    {
        vector<string> ans;
        string n = "";
        for (char i : s)
            if (i == ' ')
                ans.emplace_back(n), n = "";
            else
                n += i;
        ans.emplace_back(n);
        return ans;
    }
    vector<vector<string>> substr(vector<string> word)
    {
        vector<vector<string>> ans;
        for (int i = 0; i < word.size(); ++i)
        {
            string s = word[i];
            ans.emplace_back(vector<string>());
            for (int j = 0; j < s.length(); ++j)
            {
                string x = s;
                x.erase(x.begin() + j);
                ans[i].emplace_back(x);
            }
        }
        return ans;
    }

public:
    vector<vector<string>> findLadders(string beginWord, string endWord, vector<string> &wordList)
    {
        int pd = -1, id = 0, n = wordList.size() + 1, m = wordList[0].length();
        vector<int> vis(n);
        map<pair<int, string>, int> mp;
        vector<vector<int>> num(n * m + m, vector<int>()); //存入wordlist下标,从1开始
        wordList.emplace_back(beginWord);                  //初始点也需要处理
        vector<vector<string>> sub = substr(wordList), ans;
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
            {
                string x = sub[i][j];
                if (!mp[{j, x}])
                    mp[{j, x}] = ++id;
                num[mp[{j, x}]].emplace_back(i);
            }
        queue<iis> q;
        q.push({n - 1, beginWord});
        while (q.size())
        {
            int t = q.size(), flag = 0;
            while (t--)
            {
                iis now = q.front();
                q.pop();
                if (wordList[now.x] == endWord)
                {
                    ans.emplace_back(tos(now.s));
                    flag = 1;
                    continue;
                }
                vis[now.x] = 1;
                for (int i = 0; i < m; ++i)
                {
                    int k = mp[{i, sub[now.x][i]}];
                    for (int j = 0; j < num[k].size(); ++j)
                    {
                        int y = num[k][j];
                        if (!vis[y])
                            q.push({y, now.s + " " + wordList[y]});
                    }
                }
            }
            if (flag)
                break;
        }
        return ans;
    }
};
复制代码

 

【Over】

posted @   Renhr  阅读(21)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示