我们有一个项的集合,其中第 i 项的值为 values[i],标签为 labels[i]。
我们从这些项中选出一个子集 S,这样一来:
|S| <= num_wanted
对于任意的标签 L,子集 S 中标签为 L 的项的数目总满足 <= use_limit。
返回子集 S 的最大可能的 和。
示例 1:
输入:values = [5,4,3,2,1], labels = [1,1,2,2,3], num_wanted = 3, use_limit = 1
输出:9
解释:选出的子集是第一项,第三项和第五项。
示例 2:
输入:values = [5,4,3,2,1], labels = [1,3,3,3,2], num_wanted = 3, use_limit = 2
输出:12
解释:选出的子集是第一项,第二项和第三项。
示例 3:
输入:values = [9,8,8,7,6], labels = [0,0,0,1,1], num_wanted = 3, use_limit = 1
输出:16
解释:选出的子集是第一项和第四项。
示例 4:
输入:values = [9,8,8,7,6], labels = [0,0,0,1,1], num_wanted = 3, use_limit = 2
输出:24
解释:选出的子集是第一项,第二项和第四项。
提示:
1 <= values.length == labels.length <= 20000
0 <= values[i], labels[i] <= 20000
1 <= num_wanted, use_limit <= values.length
分析:本题是贪心算法题,既然是选择最大和,那么局部最优解就是拿满足条件的最大的值,然后次大的以此类推
首先需要将值按照从大到小排序,注意对应的标号不要打乱
然后直接从头遍历数组,满足条件就加上,贪心算法,只考虑最优
//手写一个快排,速度快,方便
void sort(int* a,int* b,int l,int r)
{
int i=l,j=r;
if(i>=j) return;
int k=a[i];
int t=b[i];
while(i=k)i++;
a[j]=a[i];
b[j]=b[i];
}
a[i]=k;
b[i]=t;
sort(a,b,l,i-1);
sort(a,b,i+1,r);
}
int largestValsFromLabels(int* values, int valuesSize, int* labels, int labelsSize, int num_wanted, int use_limit){
int i,j;
sort(values,labels,0,valuesSize-1);
int max=0;
int map[20001]={0}; //设置map统计每个标号引用次数
int vc=0;
for(i=0;i
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/largest-values-from-labels
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。