思路:
两个数组,要形成映射,也就是要组合起来才能排序,求子集和最大
注意:有两个限制条件,子集内元素个数<=numWanted , 重复元素个数useLimit
形成组合用vector存pair<int,int>,用lamada表达式写仿函数提供比较
有两个比较首先是让labels标签升序,选不超uselimit重复的所有标签,并且当标签相同时,让value更大的靠前,也就是第二比较册略是升序value
还没有完,这样得到的集合,还要进行去重,重复限制是uselimit
去重后,还要对unique_vec进行value排序,因为之前的排序是为了去重,同时尽可能保留每一组标签的值最大
此时unique_vec的性质是,每个标签不会多于uselimit,并且保留的标签都是那一组标签的值最大的
因为还有子集数量的限制,所以再进行对值的sort,让value更大的靠前
/*
*/
class Solution {
public:
int largestValsFromLabels(vector<int> & values, vector<int> & labels,
int numWanted, int useLimit) {
int n = values.size();
vector<pair<int, int>> vec(n);
for (int i = 0; i < n; i++) {
vec[i].first = values[i];
vec[i].second = labels[i];
}
//这个sort,按标签升序,并且标签组内按其value降序
sort(vec.begin(), vec.end(), [](pair<int, int> & p1, pair<int, int> & p2) {
if (p1.second != p2.second)
return p1.second < p2.second;//为去重做准备
else
return p1.first > p2.first;//保证去重后较大的值的标签靠前,别把大值的标签去重删了
});
for (auto x : vec) {
cout << x.first << " " << x.second << endl;
}
int last = vec[0].second;
int count = 1;
vector<pair<int, int>> unique_vec;
unique_vec.push_back(vec[0]);
for (int i = 1; i < n; i++) {
if (vec[i].second == last) {
if (count == useLimit)
continue;
count++;
unique_vec.push_back(vec[i]);
} else {
count = 1;
unique_vec.push_back(vec[i]);
last = vec[i].second;
}
}
int sum = 0;
sort(unique_vec.begin(), unique_vec.end(), [](pair<int, int> & p1,
pair<int, int> & p2) {
return p1.first > p2.first;
});
for (int i = 0; i < numWanted && i < unique_vec.size(); i++)
sum += unique_vec[i].first;
return sum;
}
};