开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第20天,点击查看活动详情
问题描述
给你一个 n 个点的无向图,节点从 0 到 n - 1 编号。给你一个长度为 n 下标从 0 开始的整数数组 vals ,其中 vals[i] 表示第 i 个节点的值。
同时给你一个二维整数数组 edges ,其中 edges[i] = [ai, bi] 表示节点 ai 和 bi 之间有一条双向边。
星图 是给定图中的一个子图,它包含一个中心节点和 0 个或更多个邻居。换言之,星图是给定图中一个边的子集,且这些边都有一个公共节点。
下图分别展示了有 3 个和 4 个邻居的星图,蓝色节点为中心节点。
星和 定义为星图中所有节点值的和。
给你一个整数 k ,请你返回 至多 包含 k 条边的星图中的 最大星和 。
示例 1:
输入: vals = [1,2,3,4,10,-10,-20], edges = [[0,1],[1,2],[1,3],[3,4],[3,5],[3,6]], k = 2
输出: 16
解释: 上图展示了输入示例。
最大星和对应的星图在上图中用蓝色标出。中心节点是 3 ,星图中还包含邻居 1 和 4 。
无法得到一个和大于 16 且边数不超过 2 的星图。
示例 2:
输入: vals = [-5], edges = [], k = 0
输出: -5
解释: 只有一个星图,就是节点 0 自己。
所以我们返回 -5 。
提示:
n == vals.length1 <= n <= 10^5-10^4 <= vals[i] <= 10^40 <= edges.length <= min(n * (n - 1) / 2``, 10^5)edges[i].length == 20 <= ai, bi <= n - 1ai != bi0 <= k <= n - 1
思路分析
题目的描述看起来可能有点复杂,首先我们应该要先理清一下题意,题目会给我们三个参数,分别是:
- vals:每个节点的值
- edges:节点的连通情况
- k:我们能取的最多的边数
题目要我们找到 至多 包含 k 条边的星图中的 最大星和 ,星图的定义是:
给定图中的一个子图,它包含一个中心节点和 `0` 个或更多个邻居。换言之,星图是给定图中一个边的子集,且这些边都有一个公共节点。也就是说星图有一个中心节点,其他节点与中心节点之间都必须要直接相连。
理清了星图的定义以及题目的要求之后,我们可以发现这道题目其实并不难
- 1、统计星图
我们可以先将每个节点其周边与它直接相连的节点记录起来,这样我们得到的节点列表就是以当前节点为中心的星图。
const map = {};
for(const edg of edges){
const m0 = map[edg[0]] || [];
const m1 = map[edg[1]] || [];
m0.push(vals[edg[1]]);
m1.push(vals[edg[0]]);
map[edg[0]] = m0;
map[edg[1]] = m1;
}
- 2、计算 至多 包含
k条边的星图中的 最大星和
统计完星图的集合之后,我们便可以开始计算 至多 包含 k 条边的星图中的 最大星和,首先我们可以先对星图的值进行一个从大到小进行排序,排完序之后,我们只需要去其前k项求和即可得到一个星图之多包含k条边的最大星和。
let res = -Infinity;
for(const key in map){
const arr = map[key].sort((a,b)=>b-a);
let sum = vals[key];
for(let i = 0; i < k && i < arr.length; i++){
res = Math.max(res,sum);
sum += arr[i];
}
res = Math.max(res,sum);
}
AC代码
完整代码如下:
/**
* @param {number[]} vals
* @param {number[][]} edges
* @param {number} k
* @return {number}
*/
var maxStarSum = function(vals, edges, k) {
if(edges.length == 0) return Math.max(...vals);
const map = {};
for(const edg of edges){
const m0 = map[edg[0]] || [];
const m1 = map[edg[1]] || [];
m0.push(vals[edg[1]]);
m1.push(vals[edg[0]]);
map[edg[0]] = m0;
map[edg[1]] = m1;
}
let res = -Infinity;
for(const key in map){
const arr = map[key].sort((a,b)=>b-a);
let sum = vals[key];
for(let i = 0; i < k && i < arr.length; i++){
res = Math.max(res,sum);
sum += arr[i];
}
res = Math.max(res,sum);
}
return res;
};
说在后面
本人为算法业余爱好者,平时只是随着兴趣偶尔刷刷题,如果上面分享有错误的地方,欢迎指出,感激不尽。