夯实算法-受标签影响的最大值

141 阅读1分钟

题目:受标签影响的最大值

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

解题思路

这道题我们要在label不超过useLimit的情况下,尽可能地找到比较大的value,可以将value-label这个组合包装到一个类中,然后存入数组pairs中按照value降序排序。 之后遍历pairs数组,如果当前value的label数量没有超出限制,则将value值累加。 我们用一个HashMap来存储已经使用的label数量。

先用map记录已经使用的某个label的数量 然后将values和labels转换成一个二维数组,对这个数组的value从大到小排序。 然后遍历二维数组,过滤结果

贪心的把所有节点按照values排序,依次选择加入结果集,当节点满足要求即(相同labels数目<=use_limit)加入贪心结果集,反之跳过,直至循环结束(结果集总个数< num_wanted)

代码实现

public int largestValsFromLabels(int[] values, int[] labels, int num_wanted, int use_limit) {
    HashMap < Integer, Integer > map = new HashMap < > ();
    for (int i: labels) {
        map.put(i, 0);
    }
    int[][] pair = new int[values.length][2];
    for (int i = 0; i < values.length; i++) {
        pair[i][0] = values[i];
        pair[i][1] = labels[i];
    }
    Arrays.sort(pair, (a, b) - > (b[0] - a[0]));
    int sum = 0;
    for (int i = 0; i < pair.length; i++) {
        int value = pair[i][0];
        int label = pair[i][1];
        if (num_wanted > 0 && map.get(label) < use_limit) {
            num_wanted--;
            map.put(label, map.get(label) + 1);
            sum += value;
        }
    }
    return sum;
}

运行结果

Snipaste_2023-04-25_22-52-07.png

复杂度分析

  • 空间复杂度:O(n)
  • 时间复杂度:O(n^2)

掘金(JUEJIN) 一起分享知识, Keep Learning!