来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/loud-and-rich

题目描述

有一组 n 个人作为实验对象,从 0 到 n - 1 编号,其中每个人都有不同数目的钱,以及不同程度的安静值(quietness)。为了方便起见,我们将编号为 x 的人简称为 "person x "。

给你一个数组 richer ,其中 richer[i] = [ai, bi] 表示 person ai 比 person bi 更有钱。另给你一个整数数组 quiet ,其中 quiet[i] 是 person i 的安静值。richer 中所给出的数据 逻辑自恰(也就是说,在 person x 比 person y 更有钱的同时,不会出现 person y 比 person x 更有钱的情况 )。

现在,返回一个整数数组 answer 作为答案,其中 answer[x] = y 的前提是,在所有拥有的钱肯定不少于 person x 的人中,person y 是最安静的人(也就是安静值 quiet[y] 最小的人)。

示例 1:

输入:richer = [[1,0],[2,1],[3,1],[3,7],[4,3],[5,3],[6,3]], quiet = [3,2,5,4,6,1,7,0]
输出:[5,5,2,5,4,5,6,7]
解释:
answer[0] = 5,
person 5 比 person 3 有更多的钱,person 3 比 person 1 有更多的钱,person 1 比 person 0 有更多的钱。
唯一较为安静(有较低的安静值 quiet[x])的人是 person 7,
但是目前还不清楚他是否比 person 0 更有钱。
answer[7] = 7,
在所有拥有的钱肯定不少于 person 7 的人中(这可能包括 person 3,4,5,6 以及 7),
最安静(有较低安静值 quiet[x])的人是 person 7。
其他的答案也可以用类似的推理来解释。

示例 2:

输入:richer = [], quiet = [0]
输出:[0]
 
提示:

n == quiet.length
1 <= n <= 500
0 <= quiet[i] < n
quiet 的所有值 互不相同
0 <= richer.length <= n * (n - 1) / 2
0 <= ai, bi < n
ai != bi
richer 中的所有数对 互不相同
对 richer 的观察在逻辑上是一致的

解题思路

这是一道标准的拓扑排序题

通过richer表,可以得到一张富有程度的拓扑表,通过拓扑排序的思路迭代就可以得出结果。

首先根据richer表构建一个关系表,每行记录比自己贫穷的人,并且记录比自己富有的人的人数。

从最富有的人开始依次向贫穷的人迭代,更新喧嚣值。

一个优化的点是可以用队列来记录当前最富有的值的人来避免每次从vector查找比自己富有的人的时间损耗。

源码展示

未优化前:

class Solution {
public:
vector<int> loudAndRich(vector<vector<int>>& richer, vector<int>& quiet) {
vector<vector<int>> vviRelation(0);
vector<int> viRet;
vector<int> viCount;
vviRelation.resize(quiet.size());
viCount.resize(quiet.size(), 0);
for(int i = 0; i<quiet.size(); i++)
{
viRet.push_back(i);
}
for(auto person:richer)
{
vviRelation[person[0]].push_back(person[1]);
viCount[person[1]]++;
}
for(int i=0; i<quiet.size(); i++)
{
int iPos = find(viCount.begin(), viCount.end(), 0) - viCount.begin();
for(auto person :vviRelation[iPos])
{
if(quiet[iPos] < quiet[person])
{
viRet[person] = viRet[iPos];
quiet[person] = quiet[iPos];
}
viCount[person]--;
}
viCount[iPos]--;
}
return viRet;
}
};

优化后:

class Solution {
public:
vector<int> loudAndRich(vector<vector<int>>& richer, vector<int>& quiet) {
vector<vector<int>> vviRelation(0);
vector<int> viRet;
vector<int> viCount;
vviRelation.resize(quiet.size());
viCount.resize(quiet.size(), 0);
queue<int> qiVisiting;
for(int i = 0; i<quiet.size(); i++)
{
viRet.push_back(i);
}
for(auto person:richer)
{
vviRelation[person[0]].push_back(person[1]);
viCount[person[1]]++;
}
for(int i=0; i<quiet.size(); i++)
{
if(viCount[i] == 0)
{
qiVisiting.push(i);
}
}
while(!qiVisiting.empty())
{
int iPos = qiVisiting.front();
qiVisiting.pop();
for(auto person :vviRelation[iPos])
{
if(quiet[viRet[iPos]] < quiet[viRet[person]])
{
viRet[person] = viRet[iPos];
}
viCount[person]--;
if(viCount[person] == 0)
{
qiVisiting.push(person);
}
}
}
return viRet;
}
};

运行结果

LeetCode-851 喧嚣与富有的更多相关文章

  1. [LeetCode] 851. Loud and Rich_ Medium tag: DFS

    In a group of N people (labelled 0, 1, 2, ..., N-1), each person has different amounts of money, and ...

  2. [LeetCode] All questions numbers conclusion 所有题目题号

    Note: 后面数字n表明刷的第n + 1遍, 如果题目有**, 表明有待总结 Conclusion questions: [LeetCode] questions conclustion_BFS, ...

  3. [LeetCode] questions conclustion_BFS, DFS

    BFS, DFS 的题目总结. Directed graph: Directed Graph Loop detection and if not have, path to print all pat ...

  4. C#LeetCode刷题-深度优先搜索

    深度优先搜索篇 # 题名 刷题 通过率 难度 98 验证二叉搜索树   22.2% 中等 99 恢复二叉搜索树   45.1% 困难 100 相同的树   48.1% 简单 101 对称二叉树   4 ...

  5. [LeetCode] Loud and Rich 聒噪与富有

    In a group of N people (labelled 0, 1, 2, ..., N-1), each person has different amounts of money, and ...

  6. 【LeetCode】851. Loud and Rich 解题报告(Python)

    [LeetCode]851. Loud and Rich 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http:// ...

  7. LeetCode最富有客户的资产总量

    最富有客户的资产总量 题目描述 给你一个 m * n 的整数网格 accounts,其中 account[i][j]是第 i 位客户在第 j 家银行托管的资产数量.返回最富有客户所拥有的资产总量. 客 ...

  8. 边工作边刷题:70天一遍leetcode: day 85-1

    Inorder Successor in BST 要点:这题要注意的是如果不是BST,没法从树结构上从root向那边找p,只能遍历.而根据BST,可以只走正确方向 如果不检查right子树,可以从ro ...

  9. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

  10. All LeetCode Questions List 题目汇总

    All LeetCode Questions List(Part of Answers, still updating) 题目汇总及部分答案(持续更新中) Leetcode problems clas ...

随机推荐

  1. MySQL简介、下载、密码修改及基本使用

    目录 存取数据的演变史 数据库软件应用史 数据库的本质 数据库的分类 MySQL简介 MySQL基本使用 系统服务的制作 密码相关操作 SQL与NoSQL 数据库重要概念 基本SQL语句 存取数据的演 ...

  2. [编程基础] Python装饰器入门总结

    Python装饰器教程展示了如何在Python中使用装饰器基本功能. 文章目录 1 使用教程 1.1 Python装饰器简单示例 1.2 带@符号的Python装饰器 1.3 用参数修饰函数 1.4 ...

  3. 一文读懂 Kubernetes 存储设计

    在 Docker 的设计中,容器内的文件是临时存放的,并且随着容器的删除,容器内部的数据也会一同被清空.不过,我们可以通过在 docker run 启动容器时,使用 --volume/-v 参数来指定 ...

  4. [LeetCode]226.翻转二叉树——递归遍历交换孩子

    题目   翻转一棵二叉树. 4 / \ 2 7 / \ / \ 1 3 6 9 //转换为: 4 / \ 7 2 / \ / \ 9 6 3 1 代码 TreeNode* invertTree(Tre ...

  5. [cocos2d-x]registerScriptHandler和registerScriptTapHandler区别

    一 .调用registerScriptHandler 的对象不同相应的响应函数和调用方式也不相同 1. 对象为layer时调用方式为: local function onNodeEvent(event ...

  6. 题解P4474 王者之剑

    双倍经验 简要题意 给你一个 \(n\times m\) 的网格,数字在格子里,你需要取出一些格子,使得任意两个格子之间没有公共边,输出格子中的数字和的最大值. \(1 \le n,m \le 100 ...

  7. 洛谷P3654 First Step题解

    这是一道暴力枚举. 大致题意:R行C列的棋盘要放下长度为K的线段,"#"表示无法放置,问有多少种放置方法. 直接贴代码: #include<bits/stdc++.h> ...

  8. Java基础学习笔记-运算符ヽ( ̄▽ ̄)و

    运算符 运算符-按功能分为7种 1.赋值运算符 广义赋值运算符 +=, -=, *=, /=, %=, &=, |= 一般形式:变量名 运算符=表达式 两侧的类型不一致会进行 自动类型转换 和 ...

  9. echarts图表配置

    1.柱状图 option = { xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] ...

  10. 大公司为什么禁止SpringBoot项目使用Tomcat?

    本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...