最小基因变化

原题在这里

  概述题意:给定初始和结束字符串和字符串数组,问每次只固定变化一个单词,最少变化次数,没有则-1。

analyse:

  字符串最短路,没啥好多说的,之前写过两次:here

 

思路如下:

  将初始和字符串数组内的字符串的所有子串转入一个sub二维数组中,用map对每一个sub字符串记录id,另外用num二维数组来将sub子串id和母串下标id连接表示边。

  然后就是普通bfs遍历搜索。

code:

复制代码
class Solution
{
    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:
    int minMutation(string start, string end, vector<string> &bank)
    {
        /*
        对字符串建图,bfs最短路
        */
        bank.emplace_back(start);
        int n = bank.size(), m = end.length(), id = 0, step = 0;
        map<pair<int, string>, int> mp;
        vector<int> vis(n);
        vector<vector<int>> num(n * m + m, vector<int>()); //对于每一组string对应的mp下标,添加对应bank路径
        vector<vector<string>> sub = substr(bank);
        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);
            }
        }
        // bfs
        queue<int> q;
        q.push(n - 1);
        while (q.size())
        {
            int p = q.size(), flag = 0;
            while (p--)
            {
                int x = q.front();
                q.pop();
                if (bank[x] == end)
                    flag = step;
                if (vis[x])
                    continue;
                vis[x] = 1;
                for (int i = 0; i < m; ++i) //有m个子串对应路径
                {
                    int k = mp[{i, sub[x][i]}];
                    for (int j = 0; j < num[k].size(); ++j)
                    {
                        int y = num[k][j];
                        if (!vis[y])
                            q.push(y);
                    }
                }
            }
            ++step;
            if (flag)
                return flag;
        }
        return -1;
    }
};
复制代码

 

 

二刷,以前写法是套用模板,但是确实有跟简单的写法:

 

复制代码
class Solution
{
public:
    int minMutation(string startGene, string endGene, vector<string> &bank)
    {
        int n = bank.size();
        unordered_set<string> mp;
        for (int i = 0; i < n; ++i)
            mp.emplace(bank[i]);
        string t = "ACGT";
        queue<string> q;
        unordered_set<string> st;
        q.push(startGene);
        st.insert(startGene);
        int ans = 0;
        while (!q.empty())
        {
            int m = q.size();
            ans++;
            while (m--)
            {
                string now = q.front();
                q.pop();
                if (now == endGene)
                    return ans-1;
                for (int i = 0; i < 8; ++i)
                {
                    for (int j = 0; j < 4; ++j)
                    {
                        if (now[i] != t[j])
                        {
                            string temp(now);
                            temp[i] = t[j];
                            if (st.count(temp) == 0 && mp.count(temp) == 1)
                            {
                                st.insert(temp);
                                q.push(temp);
                            }
                        }
                    }
                }
            }
        }
        return -1;
    }
};
here
复制代码

 

 

 

【Over】

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