LeetCode 851:喧闹和富有

LeetCode 851:喧闹和富有

原题地址

基本思路

这题的基本思路是将富有偏序关系构建成拓扑网络。在构建answer数组时,对每一个person,定位到相应节点在拓扑图中的位置,然后进行DFS搜索,找到quiet最小的<person, value>对,记录答案。
这里要记住将<person, value>对保存在节点中,避免下一次DFS到该节点时进行重复计算,起到一个剪枝的效果。

代码

class Solution {
public:
    class node
    {
    public:
        int id;
        int minQuiet;
        int minPerson;
        std::vector<node*> richerVec;
        node(int id):id(id), minQuiet(0x7ffffff), minPerson(-1)
        {
            richerVec = std::vector<node*>();
        }
        
    };

    std::pair<int, int> findMinQuiet(node* root, vector<int>& quiet)
    {
    	//若该节点已进行过DFS遍历,可直接使用遍历结果
        if(root->minPerson != -1)
        {
            return {root->minPerson, root->minQuiet};
        }
        int minPerson = root->id;
        int minQuiet = quiet[root->id];
        //对节点的所有出边节点进行DFS遍历
        for(int i=0; i<root->richerVec.size(); i++)
        {
            pair<int, int> tmp = findMinQuiet(root->richerVec[i],quiet);
            if(tmp.second < minQuiet)
            {
                minQuiet = tmp.second;
                minPerson = tmp.first;
            }
        }
        //保存遍历结果
        root->minPerson = minPerson;
        root->minQuiet = minQuiet;
        return {minPerson, minQuiet};
    }

    vector<int> loudAndRich(vector<vector<int>>& richer, vector<int>& quiet) {
        
        int persons = quiet.size();

        //构造拓扑图节点
        std::vector<node*> nodeList(persons, nullptr);
        for(int i=0; i<persons; i++)
        {
            nodeList[i] = new node(i);
        }

        //构造拓扑图
        for(int i=0; i<richer.size() ;i++)
        {
            int poor = richer[i][1];
            int rich = richer[i][0];

            node* pt = nodeList[rich];
            nodeList[poor]->richerVec.push_back(pt);
        }
			 
	    //搜索拓扑网络,构建答案
        std::vector<int> answer(persons,-1);
        for(int i=0; i<persons; i++)
        {
            answer[i] = findMinQuiet(nodeList[i],quiet).first;
        }

        return answer;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>