携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第24天,点击查看活动详情
前言
小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标300题,记录从0到1的全过程!!
1090. 受标签影响的最大值
这是141场周赛的第二题
1090. 受标签影响的最大值
现在介绍这个题。
题目
我们有一个 n 项的集合。给出两个整数数组 values 和 labels ,第 i 个元素的值和标签分别是 values[i] 和 labels[i]。还会给出两个整数 numWanted 和 useLimit 。
从 n 个元素中选择一个子集 s :
子集 s 的大小 小于或等于 numWanted 。
s 中 最多 有相同标签的 useLimit 项。
一个子集的 分数 是该子集的值之和。
返回子集 s 的最大 分数 。
示例 1
输入:values = [5,4,3,2,1], labels = [1,1,2,2,3], numWanted = 3, useLimit = 1
输出:9
解释:选出的子集是第一项,第三项和第五项。
示例 2
输入:values = [5,4,3,2,1], labels = [1,3,3,3,2], numWanted = 3, useLimit = 2
输出:12
解释:选出的子集是第一项,第二项和第三项。
示例 3
输入:values = [9,8,8,7,6], labels = [0,0,0,1,1], numWanted = 3, useLimit = 1
输出:16
解释:选出的子集是第一项和第四项。
提示:
- n == values.length == labels.length
- 1 <= n <= 2 * 104
- 0 <= values[i], labels[i] <= 2 * 104
- 1 <= numWanted, useLimit <= n
2.解法
class Solution {
public int largestValsFromLabels(int[] values, int[] labels, int numWanted, int useLimit) {
PriorityQueue<int[]> queue = new PriorityQueue<>((o1, o2) -> o2[0]-o1[0]);
//int[0] 是值 int[1]是标签
for(int i = 0; i < labels.length; i++) {
int[] ints = {values[i], labels[i]};
queue.add(ints);
}
HashMap<Integer,Integer> map = new HashMap<>();//map key:标签 value:已经添加的次数
int res = 0;
for(int i = 0; !queue.isEmpty()&& i < numWanted; i++) {
int[] temp = queue.poll();
if(!map.containsKey(temp[1])) {
map.put(temp[1],1);
res = res + temp[0];
} else {
if(map.get(temp[1]) < useLimit) {
map.put(temp[1],map.get(temp[1]) + 1);
res = res + temp[0];
} else {
i--;
}
}
}
return res;
}
}
提交排名
解析
评论区和题解区都是对这个题目描述不清楚的吐槽哈哈哈。
仔细看题,和看好他给的示例,只要看懂了,这个题也不是很难了。
首先是遍历两个数组,通过值排序,把打的放在前面。
然后遍历queue,从最大的开始取,取出来后还需要判断这个值能不能符合要求的加到res中去,如何判断呢?就是判断这个标签已经取过多少个了,符不符合要求,所以这里又引入了一个map来存储每个标签的取值次数,当次数等于userLimit的时候就不能取这个标签的值了,就要跳过。这样就能得到题目要求的值了。
3.结束
这个题把题目看懂了还算是很好理解的,周赛第二题的话,除非是某次的实在是太难,一般我的水平就是第二题能做出来,想先做一个偶尔三题的选手,再慢慢变成每次都三题的选手,还是要加强训练啊,gogogo,刷题刷题,每天一道,三年1000道!!!!