You are given n
item's value and label as two integer arrays values
and labels
. You are also given two integers numWanted
and useLimit
.
Your task is to find a subset of items with the maximum sum of their values such that:
numWanted
.useLimit
.Return the maximum sum.
Example 1:
Input: values = [5,4,3,2,1], labels = [1,1,2,2,3], numWanted = 3, useLimit = 1
Output: 9
Explanation:
The subset chosen is the first, third, and fifth items with the sum of values 5 + 3 + 1.
Example 2:
Input: values = [5,4,3,2,1], labels = [1,3,3,3,2], numWanted = 3, useLimit = 2
Output: 12
Explanation:
The subset chosen is the first, second, and third items with the sum of values 5 + 4 + 3.
Example 3:
Input: values = [9,8,8,7,6], labels = [0,0,0,1,1], numWanted = 3, useLimit = 1
Output: 16
Explanation:
The subset chosen is the first and fourth items with the sum of values 9 + 7.
Constraints:
n == values.length == labels.length
1 <= n <= 2 * 104
0 <= values[i], labels[i] <= 2 * 104
1 <= numWanted, useLimit <= n
This problem requires finding a subset of items with the maximum sum of values, subject to two constraints: the number of items is at most numWanted
, and the number of items with the same label is at most useLimit
. The optimal approach is a greedy algorithm combined with sorting and efficient data structures.
Approach:
Pairing Values and Labels: We first create pairs of (value, label)
from the input arrays values
and labels
. This allows us to easily track both pieces of information together.
Sorting by Value: We sort these pairs in descending order based on their values. This ensures that we consider the highest-value items first, maximizing the sum.
Counting Labels: We use a dictionary or hash map (cnt
in the code) to keep track of how many items with each label have already been included in our subset.
Greedy Selection: We iterate through the sorted pairs. For each pair:
cnt[label]
) is less than useLimit
, we can include this item.cnt[label] += 1
) and add the item's value to the total sum (ans += value
).num
) to keep track of the total number of items selected.numWanted
items or we've iterated through all pairs.Return the Maximum Sum: Finally, we return the accumulated sum ans
.
Time Complexity Analysis:
Space Complexity Analysis:
cnt
dictionary (or hash map) is at most O(M), where M is the number of unique labels. In the worst case, M could be N, but often it's much smaller.Code Examples (with detailed comments):
The provided code examples in Python, Java, C++, Go, and TypeScript all implement this algorithm. The core logic remains consistent across languages, with only syntax and data structure implementations varying slightly. For example, Python uses Counter
for efficient label counting, while Java and C++ use HashMap
and unordered_map
, respectively. The Go code uses Go's built-in maps. TypeScript uses a Map
. The choice of data structure affects the specific performance in different contexts (some have better worst-case performance than others).
The comments in the provided code further clarify the steps of the algorithm. The choice of using a negative value in the C++ example to simplify the sorting in a slightly less readable fashion is a matter of stylistic choice. The alternative is to use a custom comparator, which would make the code clearer at a small performance cost.