leetcode
leetcode 1001 ~ 1050
受标签影响的最大值

受标签影响的最大值

难度:

标签:

题目描述

代码结果

运行时间: 35 ms, 内存: 20.7 MB


/*
 * 思路:
 * 1. 创建一个数组表示每个元素的值和标签。
 * 2. 按照值从大到小对元素进行排序。
 * 3. 使用一个哈希表记录每个标签的使用次数。
 * 4. 使用Stream API遍历排序后的数组,选择不超过 numWanted 个元素,并且每个标签不超过 useLimit 次。
 * 5. 返回选择的元素值之和。
 */
import java.util.*;
import java.util.stream.*;

public class Solution {
    public int largestValsFromLabels(int[] values, int[] labels, int numWanted, int useLimit) {
        int n = values.length;
        List<int[]> items = IntStream.range(0, n)
                                      .mapToObj(i -> new int[]{values[i], labels[i]})
                                      .sorted((a, b) -> Integer.compare(b[0], a[0]))
                                      .collect(Collectors.toList());
        Map<Integer, Long> labelCount = new HashMap<>();
        int[] sum = {0};
        int[] count = {0};
        items.stream()
             .filter(item -> {
                 int label = item[1];
                 labelCount.put(label, labelCount.getOrDefault(label, 0L) + 1);
                 if (labelCount.get(label) <= useLimit && count[0] < numWanted) {
                     sum[0] += item[0];
                     count[0]++;
                     return true;
                 } else {
                     labelCount.put(label, labelCount.get(label) - 1);
                     return false;
                 }
             })
             .collect(Collectors.toList());
        return sum[0];
    }
}

解释

方法:

此题解的基本思路是首先将元素按照其值进行排序,然后从值最大的元素开始选择,确保不超过每个标签的使用限制 `useLimit` 和总数不超过 `numWanted`。这样可以保证所选的子集有可能是最大值。具体步骤包括: 1. 创建一个包含值和标签对的列表。 2. 将这个列表按值进行排序。 3. 使用一个字典来跟踪每个标签已经使用的次数。 4. 从列表的末尾(值最大的位置)开始,如果当前元素的标签使用次数没有达到 `useLimit`,则将其加入到结果中,并更新标签的使用次数。 5. 检查是否已经选择了 `numWanted` 个元素,如果是,则结束选择。 6. 最后返回所有选中元素值的总和。

时间复杂度:

O(n log n)

空间复杂度:

O(n)

代码细节讲解

🦆
在算法中如何保证当标签的使用次数已达到useLimit时,不再选择该标签的元素?
在算法中,我们使用一个字典`cap_dict`来记录每个标签的使用次数。在考虑是否选择一个元素时,我们首先检查这个元素的标签在`cap_dict`中的计数是否已经达到了`useLimit`。如果未达到,我们才会选择这个元素并增加该标签的使用次数;如果已达到,我们则跳过这个元素,继续检查下一个元素。这样通过`cap_dict`来控制,确保不会超过每个标签的使用限制。
🦆
对于包含重复值但不同标签的元素,此算法是如何处理的?例如values中多个元素值相同但标签不同。
算法首先将所有元素按照值进行排序,无论它们的标签是否相同。在选择元素时,即使几个元素的值相同,它们的标签可能不同,因此它们被视为独立的条目。算法会根据每个元素的标签独立判断是否可以被选中,这意味着即使值相同的不同标签的元素也可以被分别考虑,只要它们的标签的使用次数未达到限制。
🦆
排序后为什么选择从列表末尾开始迭代?迭代从最大值开始有什么特别的优势吗?
在这个问题中,我们的目标是找出值的总和最大的子集。对列表进行排序后,列表末尾的元素是值最大的。从末尾开始迭代可以直接访问这些最大值,这样可以更快地累积较大的值,从而可能达到更高的总和。此方法确保我们首先考虑较大的数值,这是寻找最大值总和子集的一个有效策略。
🦆
如果在达到numWanted选择的数量之前就遍历完了所有的元素,这种情况下算法的输出会怎样?
如果在达到`numWanted`指定的数量之前就遍历完所有元素,算法将会结束迭代并返回当前已选择的元素的值的总和。这意味着最终结果可能不会包含`numWanted`个元素,而是包含了能够在给定的标签使用限制下找到的最大值总和的元素集合。

相关问题