[LeetCode] 1090. Largest Values From Labels 標簽中的最大價值



We have a set of items: the i-th item has value values[i] and label labels[i].

Then, we choose a subset S of these items, such that:

  • |S| <= num_wanted
  • For every label L, the number of items in S with label L is <= use_limit.

Return the largest possible sum of the subset S.

Example 1:

Input: values = [5,4,3,2,1], labels = [1,1,2,2,3], `num_wanted` = 3, use_limit = 1
Output: 9
Explanation: The subset chosen is the first, third, and fifth item.

Example 2:

Input: values = [5,4,3,2,1], labels = [1,3,3,3,2], `num_wanted` = 3, use_limit = 2
Output: 12
Explanation: The subset chosen is the first, second, and third item.

Example 3:

Input: values = [9,8,8,7,6], labels = [0,0,0,1,1], `num_wanted` = 3, use_limit = 1
Output: 16
Explanation: The subset chosen is the first and fourth item.

Example 4:

Input: values = [9,8,8,7,6], labels = [0,0,0,1,1], `num_wanted` = 3, use_limit = 2
Output: 24
Explanation: The subset chosen is the first, second, and fourth item.

Note:

  1. 1 <= values.length == labels.length <= 20000
  2. 0 <= values[i], labels[i] <= 20000
  3. 1 <= num_wanted, use_limit <= values.length

這道題說是給了一堆物品,每個物品有不同的價值和標簽,分別放在 values 和 labels 數組中,現在讓選不超過 num_wanted 個物品,且每個標簽類別的物品不超過 use_limit,問能得到的最大價值是多少。說實話這道題博主研究了好久才弄懂題意,而且主要是看例子分析出來的,看了看踩比贊多,估計許多人跟博主一樣吧。這道題可以用貪婪算法來做,因為需要盡可能的選價值高的物品,但同時要兼顧到物品的標簽種類。所以可以將價值和標簽種類組成一個 pair 對兒,放到一個優先隊列中,這樣就可以按照價值從高到低進行排列了。同時,由於每個種類的物品不能超過 use_limit 個,所以需要統計每個種類被使用了多少次,可以用一個 HashMap 來建立標簽和其使用次數之間的映射。先遍歷一遍所有物品,將價值和標簽組成 pair 對兒加入優先隊列中。然后進行循環,條件是 num_wanted 大於0,且隊列不為空,此時取出隊頂元素,將其標簽映射值加1,若此時仍小於 use_limit,說明當前物品可以入選,將其價值加到 res 中,並且 num_wanted 自減1即可,參見代碼如下:


class Solution {
public:
    int largestValsFromLabels(vector<int>& values, vector<int>& labels, int num_wanted, int use_limit) {
        int res = 0, n = values.size();
        priority_queue<pair<int, int>> pq;
        unordered_map<int, int> useMap;
        for (int i = 0; i < n; ++i) {
            pq.push({values[i], labels[i]});
        }
        while (num_wanted > 0 && !pq.empty()) {
            int value = pq.top().first, label = pq.top().second; pq.pop();
            if (++useMap[label] <= use_limit) {
                res += value;
                --num_wanted;
            }
        }
        return res;
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1090


參考資料:

https://leetcode.com/problems/largest-values-from-labels/

https://leetcode.com/problems/largest-values-from-labels/discuss/312720/C%2B%2B-Greedy

https://leetcode.com/problems/largest-values-from-labels/discuss/313011/Question-Explanation-and-Simple-Solution-or-Java-or-100


LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM