Skip to content

Commit d80df58

Browse files
committed
feat: add solutions to lc problem: No.1090
No.1090.Largest Values From Labels
1 parent 674dfc5 commit d80df58

File tree

7 files changed

+196
-124
lines changed

7 files changed

+196
-124
lines changed

solution/1000-1099/1090.Largest Values From Labels/README.md

Lines changed: 73 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,15 @@
6060

6161
<!-- 这里可写通用的实现逻辑 -->
6262

63-
**方法一:贪心**
63+
**方法一:贪心 + 排序 + 哈希表**
64+
65+
根据题目描述,我们需要从 $n$ 个元素的集合中选出一个子集,子集元素个数不超过 $numWanted$,且子集中最多有相同标签的 $useLimit$ 项,使得子集的值之和最大。因此,我们应该贪心地选择集合中值较大的元素,同时记录每个标签出现的次数,当某个标签出现的次数达到 $useLimit$ 时,我们就不能再选择该标签对应的元素了。
66+
67+
具体地,我们先将集合中的元素按照值从大到小进行排序,然后从前向后遍历排序后的元素。在遍历的过程中,我们使用一个哈希表 $cnt$ 记录每个标签出现的次数,如果某个标签出现的次数达到了 $useLimit$,那么我们就跳过该元素,否则我们就将该元素的值加到最终的答案中,并将该标签出现的次数加 $1$。同时,我们用一个变量 $num$ 记录当前子集中的元素个数,当 $num$ 达到 $numWanted$ 时,我们就可以结束遍历了。
68+
69+
遍历结束后,我们就得到了最大的分数。
70+
71+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是集合中的元素个数。
6472

6573
<!-- tabs:start -->
6674

@@ -73,17 +81,15 @@ class Solution:
7381
def largestValsFromLabels(
7482
self, values: List[int], labels: List[int], numWanted: int, useLimit: int
7583
) -> int:
76-
arr = list(zip(values, labels))
77-
arr.sort(reverse=True)
78-
cnt = Counter()
7984
ans = num = 0
80-
for v, l in arr:
85+
cnt = Counter()
86+
for v, l in sorted(zip(values, labels), reverse=True):
8187
if cnt[l] < useLimit:
8288
cnt[l] += 1
8389
num += 1
8490
ans += v
85-
if num == numWanted:
86-
break
91+
if num == numWanted:
92+
break
8793
return ans
8894
```
8995

@@ -95,20 +101,19 @@ class Solution:
95101
class Solution {
96102
public int largestValsFromLabels(int[] values, int[] labels, int numWanted, int useLimit) {
97103
int n = values.length;
98-
int[][] p = new int[n][2];
104+
int[][] pairs = new int[n][2];
99105
for (int i = 0; i < n; ++i) {
100-
p[i] = new int[] {values[i], labels[i]};
106+
pairs[i] = new int[]{values[i], labels[i]};
101107
}
102-
Arrays.sort(p, (a, b) -> b[0] - a[0]);
103-
int ans = 0;
104-
int num = 0;
105-
Map<Integer, Integer> counter = new HashMap<>();
108+
Arrays.sort(pairs, (a, b) -> b[0] - a[0]);
109+
Map<Integer, Integer> cnt = new HashMap<>();
110+
int ans = 0, num = 0;
106111
for (int i = 0; i < n && num < numWanted; ++i) {
107-
int v = p[i][0], l = p[i][1];
108-
if (counter.getOrDefault(l, 0) < useLimit) {
109-
counter.put(l, counter.getOrDefault(l, 0) + 1);
112+
int v = pairs[i][0], l = pairs[i][1];
113+
if (cnt.getOrDefault(l, 0) < useLimit) {
114+
cnt.merge(l, 1, Integer::sum);
115+
num += 1;
110116
ans += v;
111-
++num;
112117
}
113118
}
114119
return ans;
@@ -123,15 +128,17 @@ class Solution {
123128
public:
124129
int largestValsFromLabels(vector<int>& values, vector<int>& labels, int numWanted, int useLimit) {
125130
int n = values.size();
126-
vector<pair<int, int>> p;
127-
for (int i = 0; i < n; ++i) p.emplace_back(values[i], labels[i]);
128-
sort(p.begin(), p.end());
129-
unordered_map<int, int> counter;
131+
vector<pair<int, int>> pairs(n);
132+
for (int i = 0; i < n; ++i) {
133+
pairs[i] = {-values[i], labels[i]};
134+
}
135+
sort(pairs.begin(), pairs.end());
136+
unordered_map<int, int> cnt;
130137
int ans = 0, num = 0;
131-
for (int i = n - 1; i >= 0 && num < numWanted; --i) {
132-
int v = p[i].first, l = p[i].second;
133-
if (counter[l] < useLimit) {
134-
++counter[l];
138+
for (int i = 0; i < n && num < numWanted; ++i) {
139+
int v = -pairs[i].first, l = pairs[i].second;
140+
if (cnt[l] < useLimit) {
141+
++cnt[l];
135142
++num;
136143
ans += v;
137144
}
@@ -144,28 +151,52 @@ public:
144151
### **Go**
145152
146153
```go
147-
func largestValsFromLabels(values []int, labels []int, numWanted int, useLimit int) int {
148-
var p [][]int
149-
for i, v := range values {
150-
p = append(p, []int{v, labels[i]})
154+
func largestValsFromLabels(values []int, labels []int, numWanted int, useLimit int) (ans int) {
155+
n := len(values)
156+
pairs := make([][2]int, n)
157+
for i := 0; i < n; i++ {
158+
pairs[i] = [2]int{values[i], labels[i]}
151159
}
152-
sort.Slice(p, func(i, j int) bool {
153-
return p[i][0] > p[j][0]
154-
})
155-
counter := make(map[int]int)
156-
ans, num := 0, 0
157-
for _, t := range p {
158-
if num >= numWanted {
159-
break
160-
}
161-
v, l := t[0], t[1]
162-
if counter[l] < useLimit {
163-
counter[l]++
160+
sort.Slice(pairs, func(i, j int) bool { return pairs[i][0] > pairs[j][0] })
161+
cnt := map[int]int{}
162+
for i, num := 0, 0; i < n && num < numWanted; i++ {
163+
v, l := pairs[i][0], pairs[i][1]
164+
if cnt[l] < useLimit {
165+
cnt[l]++
164166
num++
165167
ans += v
166168
}
167169
}
168-
return ans
170+
return
171+
}
172+
```
173+
174+
### **TypeScript**
175+
176+
```ts
177+
function largestValsFromLabels(
178+
values: number[],
179+
labels: number[],
180+
numWanted: number,
181+
useLimit: number,
182+
): number {
183+
const n = values.length;
184+
const pairs = new Array(n);
185+
for (let i = 0; i < n; ++i) {
186+
pairs[i] = [values[i], labels[i]];
187+
}
188+
pairs.sort((a, b) => b[0] - a[0]);
189+
const cnt: Map<number, number> = new Map();
190+
let ans = 0;
191+
for (let i = 0, num = 0; i < n && num < numWanted; ++i) {
192+
const [v, l] = pairs[i];
193+
if ((cnt.get(l) || 0) < useLimit) {
194+
cnt.set(l, (cnt.get(l) || 0) + 1);
195+
++num;
196+
ans += v;
197+
}
198+
}
199+
return ans;
169200
}
170201
```
171202

solution/1000-1099/1090.Largest Values From Labels/README_EN.md

Lines changed: 64 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,15 @@ class Solution:
6363
def largestValsFromLabels(
6464
self, values: List[int], labels: List[int], numWanted: int, useLimit: int
6565
) -> int:
66-
arr = list(zip(values, labels))
67-
arr.sort(reverse=True)
68-
cnt = Counter()
6966
ans = num = 0
70-
for v, l in arr:
67+
cnt = Counter()
68+
for v, l in sorted(zip(values, labels), reverse=True):
7169
if cnt[l] < useLimit:
7270
cnt[l] += 1
7371
num += 1
7472
ans += v
75-
if num == numWanted:
76-
break
73+
if num == numWanted:
74+
break
7775
return ans
7876
```
7977

@@ -83,20 +81,19 @@ class Solution:
8381
class Solution {
8482
public int largestValsFromLabels(int[] values, int[] labels, int numWanted, int useLimit) {
8583
int n = values.length;
86-
int[][] p = new int[n][2];
84+
int[][] pairs = new int[n][2];
8785
for (int i = 0; i < n; ++i) {
88-
p[i] = new int[] {values[i], labels[i]};
86+
pairs[i] = new int[]{values[i], labels[i]};
8987
}
90-
Arrays.sort(p, (a, b) -> b[0] - a[0]);
91-
int ans = 0;
92-
int num = 0;
93-
Map<Integer, Integer> counter = new HashMap<>();
88+
Arrays.sort(pairs, (a, b) -> b[0] - a[0]);
89+
Map<Integer, Integer> cnt = new HashMap<>();
90+
int ans = 0, num = 0;
9491
for (int i = 0; i < n && num < numWanted; ++i) {
95-
int v = p[i][0], l = p[i][1];
96-
if (counter.getOrDefault(l, 0) < useLimit) {
97-
counter.put(l, counter.getOrDefault(l, 0) + 1);
92+
int v = pairs[i][0], l = pairs[i][1];
93+
if (cnt.getOrDefault(l, 0) < useLimit) {
94+
cnt.merge(l, 1, Integer::sum);
95+
num += 1;
9896
ans += v;
99-
++num;
10097
}
10198
}
10299
return ans;
@@ -111,15 +108,17 @@ class Solution {
111108
public:
112109
int largestValsFromLabels(vector<int>& values, vector<int>& labels, int numWanted, int useLimit) {
113110
int n = values.size();
114-
vector<pair<int, int>> p;
115-
for (int i = 0; i < n; ++i) p.emplace_back(values[i], labels[i]);
116-
sort(p.begin(), p.end());
117-
unordered_map<int, int> counter;
111+
vector<pair<int, int>> pairs(n);
112+
for (int i = 0; i < n; ++i) {
113+
pairs[i] = {-values[i], labels[i]};
114+
}
115+
sort(pairs.begin(), pairs.end());
116+
unordered_map<int, int> cnt;
118117
int ans = 0, num = 0;
119-
for (int i = n - 1; i >= 0 && num < numWanted; --i) {
120-
int v = p[i].first, l = p[i].second;
121-
if (counter[l] < useLimit) {
122-
++counter[l];
118+
for (int i = 0; i < n && num < numWanted; ++i) {
119+
int v = -pairs[i].first, l = pairs[i].second;
120+
if (cnt[l] < useLimit) {
121+
++cnt[l];
123122
++num;
124123
ans += v;
125124
}
@@ -132,28 +131,52 @@ public:
132131
### **Go**
133132
134133
```go
135-
func largestValsFromLabels(values []int, labels []int, numWanted int, useLimit int) int {
136-
var p [][]int
137-
for i, v := range values {
138-
p = append(p, []int{v, labels[i]})
134+
func largestValsFromLabels(values []int, labels []int, numWanted int, useLimit int) (ans int) {
135+
n := len(values)
136+
pairs := make([][2]int, n)
137+
for i := 0; i < n; i++ {
138+
pairs[i] = [2]int{values[i], labels[i]}
139139
}
140-
sort.Slice(p, func(i, j int) bool {
141-
return p[i][0] > p[j][0]
142-
})
143-
counter := make(map[int]int)
144-
ans, num := 0, 0
145-
for _, t := range p {
146-
if num >= numWanted {
147-
break
148-
}
149-
v, l := t[0], t[1]
150-
if counter[l] < useLimit {
151-
counter[l]++
140+
sort.Slice(pairs, func(i, j int) bool { return pairs[i][0] > pairs[j][0] })
141+
cnt := map[int]int{}
142+
for i, num := 0, 0; i < n && num < numWanted; i++ {
143+
v, l := pairs[i][0], pairs[i][1]
144+
if cnt[l] < useLimit {
145+
cnt[l]++
152146
num++
153147
ans += v
154148
}
155149
}
156-
return ans
150+
return
151+
}
152+
```
153+
154+
### **TypeScript**
155+
156+
```ts
157+
function largestValsFromLabels(
158+
values: number[],
159+
labels: number[],
160+
numWanted: number,
161+
useLimit: number,
162+
): number {
163+
const n = values.length;
164+
const pairs = new Array(n);
165+
for (let i = 0; i < n; ++i) {
166+
pairs[i] = [values[i], labels[i]];
167+
}
168+
pairs.sort((a, b) => b[0] - a[0]);
169+
const cnt: Map<number, number> = new Map();
170+
let ans = 0;
171+
for (let i = 0, num = 0; i < n && num < numWanted; ++i) {
172+
const [v, l] = pairs[i];
173+
if ((cnt.get(l) || 0) < useLimit) {
174+
cnt.set(l, (cnt.get(l) || 0) + 1);
175+
++num;
176+
ans += v;
177+
}
178+
}
179+
return ans;
157180
}
158181
```
159182

solution/1000-1099/1090.Largest Values From Labels/Solution.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@ class Solution {
22
public:
33
int largestValsFromLabels(vector<int>& values, vector<int>& labels, int numWanted, int useLimit) {
44
int n = values.size();
5-
vector<pair<int, int>> p;
6-
for (int i = 0; i < n; ++i) p.emplace_back(values[i], labels[i]);
7-
sort(p.begin(), p.end());
8-
unordered_map<int, int> counter;
5+
vector<pair<int, int>> pairs(n);
6+
for (int i = 0; i < n; ++i) {
7+
pairs[i] = {-values[i], labels[i]};
8+
}
9+
sort(pairs.begin(), pairs.end());
10+
unordered_map<int, int> cnt;
911
int ans = 0, num = 0;
10-
for (int i = n - 1; i >= 0 && num < numWanted; --i) {
11-
int v = p[i].first, l = p[i].second;
12-
if (counter[l] < useLimit) {
13-
++counter[l];
12+
for (int i = 0; i < n && num < numWanted; ++i) {
13+
int v = -pairs[i].first, l = pairs[i].second;
14+
if (cnt[l] < useLimit) {
15+
++cnt[l];
1416
++num;
1517
ans += v;
1618
}
Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
1-
func largestValsFromLabels(values []int, labels []int, numWanted int, useLimit int) int {
2-
var p [][]int
3-
for i, v := range values {
4-
p = append(p, []int{v, labels[i]})
1+
func largestValsFromLabels(values []int, labels []int, numWanted int, useLimit int) (ans int) {
2+
n := len(values)
3+
pairs := make([][2]int, n)
4+
for i := 0; i < n; i++ {
5+
pairs[i] = [2]int{values[i], labels[i]}
56
}
6-
sort.Slice(p, func(i, j int) bool {
7-
return p[i][0] > p[j][0]
8-
})
9-
counter := make(map[int]int)
10-
ans, num := 0, 0
11-
for _, t := range p {
12-
if num >= numWanted {
13-
break
14-
}
15-
v, l := t[0], t[1]
16-
if counter[l] < useLimit {
17-
counter[l]++
7+
sort.Slice(pairs, func(i, j int) bool { return pairs[i][0] > pairs[j][0] })
8+
cnt := map[int]int{}
9+
for i, num := 0, 0; i < n && num < numWanted; i++ {
10+
v, l := pairs[i][0], pairs[i][1]
11+
if cnt[l] < useLimit {
12+
cnt[l]++
1813
num++
1914
ans += v
2015
}
2116
}
22-
return ans
17+
return
2318
}

0 commit comments

Comments
 (0)