【刷题打卡】1090. 受标签影响的最大值

134 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、题目描述:

1090. 受标签影响的最大值 - 力扣(LeetCode) (leetcode-cn.com)

我们有一个 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 * 10^4
  • 0 <= values[i], labels[i] <= 2 * 10^4
  • 1 <= numWanted, useLimit <= n

二、思路分析:

  1. 首先要清楚一点,先考虑的是如何使子集的和(result)最大,其次再考虑每个标签所用数目(count_limit)<=use_limit,最后才考虑所选项的总数(count)<=num_wanted;

  2. 先将每个value与其对应的label组成一对,保存在一个列表中,并按value大小从大到小排序;

  3. 之后,从头开始遍历,这样可以保证总是先拿到目前最大的value,同时去考虑这个value对应的labal的数目是否超过了use_limit;

  4. 要注意的是,可能存在count大小不足num_wanted的情况

三、AC 代码:

class Solution:
    def largestValsFromLabels(self, values: List[int], labels: List[int], num_wanted: int, use_limit: int) -> int:
        length = len(values)
        result_list = []
        for i in range(length):
            result_list.append((values[i], labels[i]))
        result_list.sort(reverse=True)
        count_limit = {}
        result, count = 0, 0
        for i in range(length):
            if result_list[i][1] not in count_limit:
                result += result_list[i][0]
                count += 1
                count_limit[result_list[i][1]] = 1
            elif count_limit[result_list[i][1]] < use_limit:
                result += result_list[i][0]
                count += 1
                count_limit[result_list[i][1]] += 1
            if count == num_wanted:
                break
        return result

四、总结:

最后说一点的是,当你明白题意的时候,这道题你就已经成功一半了(含蓄吐槽)