持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
每日刷题 2022.05.29
- leetcode原题链接:leetcode.cn/problems/ma…
- 难度:中等
- 方法:贪心、sort
题目
- 给你一个整数
n,表示一个国家里的城市数目。城市编号为0到n - 1。 - 给你一个二维整数数组
roads,其中roads[i] = [ai, bi]表示城市ai和bi之间有一条 双向 道路。 - 你需要给每个城市安排一个从
1到n之间的整数值,且每个值只能被使用 一次 。道路的 重要性 定义为这条道路连接的两座城市数值之和。 - 请你返回在最优安排下,所有道路重要性之和最大为多少。
示例
- 示例1
输入:n = 5, roads = [[0,1],[1,2],[2,3],[0,2],[1,3],[2,4]]
输出:43
解释:上图展示了国家图和每个城市被安排的值 [2,4,5,3,1] 。
- 道路 (0,1) 重要性为 2 + 4 = 6 。
- 道路 (1,2) 重要性为 4 + 5 = 9 。
- 道路 (2,3) 重要性为 5 + 3 = 8 。
- 道路 (0,2) 重要性为 2 + 5 = 7 。
- 道路 (1,3) 重要性为 4 + 3 = 7 。
- 道路 (2,4) 重要性为 5 + 1 = 6 。
所有道路重要性之和为 6 + 9 + 8 + 7 + 7 + 6 = 43 。
可以证明,重要性之和不可能超过 43 。
- 示例2
输入:n = 5, roads = [[0,3],[2,4],[1,3]]
输出:20
解释:上图展示了国家图和每个城市被安排的值 [4,3,2,5,1] 。
- 道路 (0,3) 重要性为 4 + 5 = 9 。
- 道路 (2,4) 重要性为 2 + 1 = 3 。
- 道路 (1,3) 重要性为 3 + 5 = 8 。
所有道路重要性之和为 9 + 3 + 8 = 20 。
可以证明,重要性之和不可能超过 20 。
提示
- 2 <= n <= 5 * 10^4
- 1 <= roads.length <= 5 * 10^4
- roads[i].length == 2
- 0 <= ai, bi <= n - 1
- ai != bi
- 没有重复道路。
解题思路
- 分析:
roads[i] = [ai, bi]表示城市ai和bi之间有一条 双向道路。也就是说是无向图,因此两个城市相连的一条道路,既是属于a城市的也是属于b城市的。 - 需要给每个城市安排一个整数值
1 ~ n,使得道路的重要性之和最大 - 那么分析到这里,使用贪心的思维可以想到,当然是城市道路数最多的乘以
n,依次往下递减这样得到的,道路重要性之和最大
具体实现
- 统计每个城市拥有的总的道路数,记为
ans数组 - 将
ans数组进行降序排序后,此时ans[0]就是最大的数,因此给ans[0] * n、ans[1] * n - 1 ..... ans[n - 1] * 1,最终将这些结果加和,就可以得到最终的结果 - 分析:有人可能会考虑,排序的时候,不是将哪个城市对应的道路总数丢失了吗?是的,其实这里没有必要再记录是哪座城市对应的道路总数,因为最终的结果只取决于:道路数 *
n ~ 1的值加和
AC代码
var maximumImportance = function(n, roads) {
let r = roads, ans = new Array(n).fill(0), m = r.length;
// 因为是 城市a和城市b之间有一条双向的通道,因此是无向图,统计每个城市出来的有几条道路
for(let i = 0; i < m; i++) {
let x = r[i][0], y = r[i][1];
ans[x]++;
ans[y]++;
}
// 将每个城市拥有的道路总数升序排序
ans.sort((a, b) => {
return b - a;
});
// 按照最大的城市道路总数 * n,这样依次往下
let sum = 0, t = n;
for(let i = 0; i < n; i++) {
sum += ans[i] * t;
t--;
}
return sum;
};
总结
- 仔细分析题目,想好后再开始写代码,比如这道题,最终的结果和哪座城市是没有关系的。