2115.从给定原材料中找到所有可以做出的菜 拓扑排序实现

好久没有记录了,今天做一道题,想到了拓扑排序,但是苦于学习的时候没有真正实现过拓扑排序,所以在代码实现的过程中遇到了重重阻碍,不得已去学习题解的写法,倒也是有了深刻的认知。

文章中引用了别人讲解unordered_map的CSDN博客,因为觉得写的很好所以贴上链接不迷路

先上代码:

class Solution 
{
public:
    vector<string> findAllRecipes(vector<string>& recipes, vector<vector<string>>& ingredients, vector<string>& supplies) 
    {
        int n = recipes.size();//菜肴数
        // 图
        unordered_map<string, vector<string>> depend;//这是一个无序关联式容器
        //对于它的用法,这里贴上别人写的博客,方便自己查找学习,讲这个容器的

        //    https://blog.csdn.net/zou_albert/article/details/106983268

        // 入度统计
        unordered_map<string, int> cnt;

        //拓扑排序的精髓就是如果一个结点的入度为0,那么它就不依赖任何其他结点
        //本题中就是意味着要么原材料,要么是可以做出来的菜
        for (int i = 0; i < n; ++i) 
        {
            //遍历某个菜的菜谱
            for (const string& ing: ingredients[i]) 
            {
                //注意这里是把原材料作为关键字key,后面的value是一个vector,存储依赖这个原材料的菜
                depend[ing].push_back(recipes[i]);
            }
            //这些个要做的菜的入度,也就是依赖的原材料个数就是菜谱中元素的个数
            cnt[recipes[i]] = ingredients[i].size();
        }
        
        vector<string> ans;
        queue<string> q;
        // 把初始的原材料放入队列
        for (const string& sup: supplies)
        {
            q.push(sup);
        }
        // 拓扑排序
        while (!q.empty())
        {
            string cur = q.front();
            //这里可以理解为有很多个盘子,一个盘子对应想做的菜。往下就开始操作了
            //最开始这里只有初始的原材料,它开始遍历,挨个看谁需要我这种原材料,需要就往盘子里放,放一个这道菜就不再需要这种原材料了,那么它的cnt,也就是入度就减一
            q.pop();
            if (depend.count(cur)) //由于不存在相同的key,所以这实际在检查图中是否有这个结点
            {
            //也就是看一看你们剩的这些菜还需不需要我这个原材料
                for (const string& rec: depend[cur]) 
                {
                //这块就是操作的主要部分了
                    --cnt[rec];
                    // 如果入度变为 0,说明可以做出这道菜
                    if (cnt[rec] == 0)
                    {
                        ans.push_back(rec);//太棒了,可以做
                        q.push(rec);//变成原材料了,放进原材料队列
                    }
                }
            }
        }
        return ans;
    }//函数体
};

这道题对于深刻理解拓扑排序有很好的帮助,精刷一道题约等与随便看看十道题,我觉得我理解了,过段时间再重新自己码一次,建议和我一样对拓扑排序的实现不太熟悉的好兄弟可以看看这道题,如果精力充足的话可以趁热打铁再来几道。

今天就写到这里吧,又学会了一个知识点嘿嘿

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值