Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e249ecb

Browse files
feat: add solutions to lc problem: No.2910 (#1871)
No.2910.Minimum Number of Groups to Create a Valid Assignment
1 parent 11f9d06 commit e249ecb

File tree

8 files changed

+481
-6
lines changed

8 files changed

+481
-6
lines changed

‎solution/2900-2999/2910.Minimum Number of Groups to Create a Valid Assignment/README.md‎

Lines changed: 166 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,34 +64,197 @@
6464

6565
<!-- 这里可写通用的实现逻辑 -->
6666

67+
**方法一:哈希表 + 枚举**
68+
69+
我们用一个哈希表 $cnt$ 统计数组 $nums$ 中每个数字出现的次数,我们记数字次数的最小值为 $k,ドル那么我们可以在 $[k,..1]$ 的范围内枚举分组的大小。由于每个组的大小差值不超过 1ドル,ドル那么分组大小为 $k$ 或 $k+1$。
70+
71+
对于当前枚举到的分组大小 $k,ドル我们遍历哈希表中的每个次数 $v,ドル如果 $\lfloor \frac{v}{k} \rfloor < v \bmod k,ドル那么说明无法将这个次数 $v$ 分成 $k$ 个或 $k+1$ 个数值相同的组,因此我们可以直接跳过这个分组大小 $k$。否则,说明可以分组,我们只需要尽可能分出最多的分组大小 $k+1,ドル即可保证得到最小的分组数,因此我们可以将 $v$ 个数分成 $\lceil \frac{v}{k+1} \rceil$ 组,累加到当前枚举的答案中。由于我们是按照 $k$ 从大到小枚举的,因此只要找到了一个合法的分组方案,那么一定是最优的。
72+
73+
时间复杂度 $O(n),ドル空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
74+
6775
<!-- tabs:start -->
6876

6977
### **Python3**
7078

7179
<!-- 这里可写当前语言的特殊实现逻辑 -->
7280

7381
```python
74-
82+
class Solution:
83+
def minGroupsForValidAssignment(self, nums: List[int]) -> int:
84+
cnt = Counter(nums)
85+
for k in range(min(cnt.values()), 0, -1):
86+
ans = 0
87+
for v in cnt.values():
88+
if v // k < v % k:
89+
ans = 0
90+
break
91+
ans += (v + k) // (k + 1)
92+
if ans:
93+
return ans
7594
```
7695

7796
### **Java**
7897

7998
<!-- 这里可写当前语言的特殊实现逻辑 -->
8099

81100
```java
82-
101+
class Solution {
102+
public int minGroupsForValidAssignment(int[] nums) {
103+
Map<Integer, Integer> cnt = new HashMap<>();
104+
for (int x : nums) {
105+
cnt.merge(x, 1, Integer::sum);
106+
}
107+
int k = nums.length;
108+
for (int v : cnt.values()) {
109+
k = Math.min(k, v);
110+
}
111+
for (;; --k) {
112+
int ans = 0;
113+
for (int v : cnt.values()) {
114+
if (v / k < v % k) {
115+
ans = 0;
116+
break;
117+
}
118+
ans += (v + k) / (k + 1);
119+
}
120+
if (ans > 0) {
121+
return ans;
122+
}
123+
}
124+
}
125+
}
83126
```
84127

85128
### **C++**
86129

87130
```cpp
88-
131+
class Solution {
132+
public:
133+
int minGroupsForValidAssignment(vector<int>& nums) {
134+
unordered_map<int, int> cnt;
135+
for (int x : nums) {
136+
cnt[x]++;
137+
}
138+
int k = 1e9;
139+
for (auto& [_, v] : cnt) {
140+
ans = min(ans, v);
141+
}
142+
for (;; --k) {
143+
int ans = 0;
144+
for (auto& [_, v] : cnt) {
145+
if (v / k < v % k) {
146+
ans = 0;
147+
break;
148+
}
149+
ans += (v + k) / (k + 1);
150+
}
151+
if (ans) {
152+
return ans;
153+
}
154+
}
155+
}
156+
};
89157
```
90158
91159
### **Go**
92160
93161
```go
162+
func minGroupsForValidAssignment(nums []int) int {
163+
cnt := map[int]int{}
164+
for _, x := range nums {
165+
cnt[x]++
166+
}
167+
k := len(nums)
168+
for _, v := range cnt {
169+
k = min(k, v)
170+
}
171+
for ; ; k-- {
172+
ans := 0
173+
for _, v := range cnt {
174+
if v/k < v%k {
175+
ans = 0
176+
break
177+
}
178+
ans += (v + k) / (k + 1)
179+
}
180+
if ans > 0 {
181+
return ans
182+
}
183+
}
184+
}
185+
186+
func min(a, b int) int {
187+
if a < b {
188+
return a
189+
}
190+
return b
191+
}
192+
```
193+
194+
### **TypeScript**
195+
196+
```ts
197+
function minGroupsForValidAssignment(nums: number[]): number {
198+
const cnt: Map<number, number> = new Map();
199+
for (const x of nums) {
200+
cnt.set(x, (cnt.get(x) || 0) + 1);
201+
}
202+
for (let k = Math.min(...cnt.values()); ; --k) {
203+
let ans = 0;
204+
for (const [_, v] of cnt) {
205+
if (((v / k) | 0) < v % k) {
206+
ans = 0;
207+
break;
208+
}
209+
ans += Math.ceil(v / (k + 1));
210+
}
211+
if (ans) {
212+
return ans;
213+
}
214+
}
215+
}
216+
```
217+
218+
### **Rust**
219+
220+
```rust
221+
use std::collections::HashMap;
222+
223+
impl Solution {
224+
pub fn min_groups_for_valid_assignment(nums: Vec<i32>) -> i32 {
225+
let mut cnt: HashMap<i32, i32> = HashMap::new();
226+
227+
for x in nums.iter() {
228+
let count = cnt.entry(*x).or_insert(0);
229+
*count += 1;
230+
}
231+
232+
let mut k = i32::MAX;
233+
234+
for &v in cnt.values() {
235+
k = k.min(v);
236+
}
237+
238+
for k in (1..=k).rev() {
239+
let mut ans = 0;
240+
241+
for &v in cnt.values() {
242+
if v / k < v % k {
243+
ans = 0;
244+
break;
245+
}
246+
247+
ans += (v + k) / (k + 1);
248+
}
249+
250+
if ans > 0 {
251+
return ans;
252+
}
253+
}
94254

255+
0
256+
}
257+
}
95258
```
96259

97260
### **...**

‎solution/2900-2999/2910.Minimum Number of Groups to Create a Valid Assignment/README_EN.md‎

Lines changed: 166 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,30 +58,193 @@ Hence, the answer is 4.</pre>
5858

5959
## Solutions
6060

61+
**Solution 1: Hash Table + Enumeration**
62+
63+
We use a hash table $cnt$ to count the number of occurrences of each number in the array $nums$. Let $k$ be the minimum value of the number of occurrences, and then we can enumerate the size of the groups in the range $[k,..1]$. Since the difference in size between each group is not more than 1ドル,ドル the group size can be either $k$ or $k+1$.
64+
65+
For the current group size $k$ being enumerated, we traverse each occurrence $v$ in the hash table. If $\lfloor \frac{v}{k} \rfloor < v \bmod k,ドル it means that we cannot divide the occurrence $v$ into $k$ or $k+1$ groups with the same value, so we can skip this group size $k$ directly. Otherwise, it means that we can form groups, and we only need to form as many groups of size $k+1$ as possible to ensure the minimum number of groups. Therefore, we can divide $v$ numbers into $\lceil \frac{v}{k+1} \rceil$ groups and add them to the current enumerated answer. Since we enumerate $k$ from large to small, as long as we find a valid grouping scheme, it must be optimal.
66+
67+
The time complexity is $O(n),ドル and the space complexity is $O(n)$. Here, $n$ is the length of the array $nums$.
68+
6169
<!-- tabs:start -->
6270

6371
### **Python3**
6472

6573
```python
66-
74+
class Solution:
75+
def minGroupsForValidAssignment(self, nums: List[int]) -> int:
76+
cnt = Counter(nums)
77+
for k in range(min(cnt.values()), 0, -1):
78+
ans = 0
79+
for v in cnt.values():
80+
if v // k < v % k:
81+
ans = 0
82+
break
83+
ans += (v + k) // (k + 1)
84+
if ans:
85+
return ans
6786
```
6887

6988
### **Java**
7089

7190
```java
72-
91+
class Solution {
92+
public int minGroupsForValidAssignment(int[] nums) {
93+
Map<Integer, Integer> cnt = new HashMap<>();
94+
for (int x : nums) {
95+
cnt.merge(x, 1, Integer::sum);
96+
}
97+
int k = nums.length;
98+
for (int v : cnt.values()) {
99+
k = Math.min(k, v);
100+
}
101+
for (;; --k) {
102+
int ans = 0;
103+
for (int v : cnt.values()) {
104+
if (v / k < v % k) {
105+
ans = 0;
106+
break;
107+
}
108+
ans += (v + k) / (k + 1);
109+
}
110+
if (ans > 0) {
111+
return ans;
112+
}
113+
}
114+
}
115+
}
73116
```
74117

75118
### **C++**
76119

77120
```cpp
78-
121+
class Solution {
122+
public:
123+
int minGroupsForValidAssignment(vector<int>& nums) {
124+
unordered_map<int, int> cnt;
125+
for (int x : nums) {
126+
cnt[x]++;
127+
}
128+
int k = 1e9;
129+
for (auto& [_, v] : cnt) {
130+
ans = min(ans, v);
131+
}
132+
for (;; --k) {
133+
int ans = 0;
134+
for (auto& [_, v] : cnt) {
135+
if (v / k < v % k) {
136+
ans = 0;
137+
break;
138+
}
139+
ans += (v + k) / (k + 1);
140+
}
141+
if (ans) {
142+
return ans;
143+
}
144+
}
145+
}
146+
};
79147
```
80148
81149
### **Go**
82150
83151
```go
152+
func minGroupsForValidAssignment(nums []int) int {
153+
cnt := map[int]int{}
154+
for _, x := range nums {
155+
cnt[x]++
156+
}
157+
k := len(nums)
158+
for _, v := range cnt {
159+
k = min(k, v)
160+
}
161+
for ; ; k-- {
162+
ans := 0
163+
for _, v := range cnt {
164+
if v/k < v%k {
165+
ans = 0
166+
break
167+
}
168+
ans += (v + k) / (k + 1)
169+
}
170+
if ans > 0 {
171+
return ans
172+
}
173+
}
174+
}
175+
176+
func min(a, b int) int {
177+
if a < b {
178+
return a
179+
}
180+
return b
181+
}
182+
```
183+
184+
### **TypeScript**
185+
186+
```ts
187+
function minGroupsForValidAssignment(nums: number[]): number {
188+
const cnt: Map<number, number> = new Map();
189+
for (const x of nums) {
190+
cnt.set(x, (cnt.get(x) || 0) + 1);
191+
}
192+
for (let k = Math.min(...cnt.values()); ; --k) {
193+
let ans = 0;
194+
for (const [_, v] of cnt) {
195+
if (((v / k) | 0) < v % k) {
196+
ans = 0;
197+
break;
198+
}
199+
ans += Math.ceil(v / (k + 1));
200+
}
201+
if (ans) {
202+
return ans;
203+
}
204+
}
205+
}
206+
```
207+
208+
### **Rust**
209+
210+
```rust
211+
use std::collections::HashMap;
212+
213+
impl Solution {
214+
pub fn min_groups_for_valid_assignment(nums: Vec<i32>) -> i32 {
215+
let mut cnt: HashMap<i32, i32> = HashMap::new();
216+
217+
for x in nums.iter() {
218+
let count = cnt.entry(*x).or_insert(0);
219+
*count += 1;
220+
}
221+
222+
let mut k = i32::MAX;
223+
224+
for &v in cnt.values() {
225+
k = k.min(v);
226+
}
227+
228+
for k in (1..=k).rev() {
229+
let mut ans = 0;
230+
231+
for &v in cnt.values() {
232+
if v / k < v % k {
233+
ans = 0;
234+
break;
235+
}
236+
237+
ans += (v + k) / (k + 1);
238+
}
239+
240+
if ans > 0 {
241+
return ans;
242+
}
243+
}
84244

245+
0
246+
}
247+
}
85248
```
86249

87250
### **...**

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /