/** 贪心:要想使子集分数最大,应选取values中较大的值。* 思路:使用一个哈希表来记录每个标签使用的次数,相同标签使其不超过useLimit限制* 对values进行降序排序,并对其进行遍历只要标签使用次数不超过限制就将较大值* 加入结果中。* 注意:因为不能改变values数组的次序所以不能直接对其进行排序,所以使用一个* 下标数组idx进行排序,idx[0]就是values中第一个最大值,idx[1]就是values* 中第二大的值,以此类推。* map中getOrDefault()方法:获取key对应的value,若map中没有key关键字,则返回自己设置的返回值。*/
public class L1090 {public int largestValsFromLabels(int[] values, int[] labels, int numWanted, int useLimit) {int n = values.length;Integer[] idx = new Integer[n];for (int i = 0; i < n; i++) {idx[i] = i;}//使用下标函数对values实现排序Arrays.sort(idx,(a,b) -> values[b] - values[a]);Map<Integer,Integer> map = new HashMap<>();//choose表示子集的大小,lab表示标签int sums = 0,choose = 0,lab = 0;for (int i = 0; i < n && choose < numWanted; i++) {//获取values中第i个最大值的标签lab = labels[idx[i]];//标签数量不能大于限制,因为lab是从0开始所以等于useLimitif (map.getOrDefault(lab,0) == useLimit)continue;choose++;//添加到结果中sums += values[idx[i]];//更改标签的使用次数map.put(lab,map.getOrDefault(lab,0)+1);}return sums;}
}