Skip to content

Commit c91d46e

Browse files
committed
Improved task 1815
1 parent 7a8057d commit c91d46e

File tree

1 file changed

+70
-40
lines changed
  • src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts

1 file changed

+70
-40
lines changed
Lines changed: 70 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,90 @@
11
package g1801_1900.s1815_maximum_number_of_groups_getting_fresh_donuts;
22

33
// #Hard #Array #Dynamic_Programming #Bit_Manipulation #Bitmask #Memoization
4-
// #2022_05_03_Time_7_ms_(86.67%)_Space_43.6_MB_(73.33%)
4+
// #2025_02_21_Time_2_ms_(100.00%)_Space_41.56_MB_(100.00%)
55

6-
import java.util.Arrays;
76
import java.util.HashMap;
87
import java.util.Map;
98

109
public class Solution {
11-
private static final Map<String, Integer> MAP = new HashMap<>();
12-
1310
public int maxHappyGroups(int batchSize, int[] groups) {
14-
int[] count = new int[batchSize];
15-
int res = 0;
16-
int remGroup = 0;
17-
for (int group : groups) {
18-
int g = group % batchSize;
19-
if (g == 0) {
20-
res++;
21-
} else if (count[batchSize - g] > 0) {
22-
remGroup--;
23-
res++;
24-
count[batchSize - g]--;
25-
} else {
26-
count[g]++;
27-
remGroup++;
28-
}
11+
if (batchSize == 1) {
12+
return groups.length;
13+
}
14+
int[] withSize = new int[batchSize];
15+
for (int size : groups) {
16+
withSize[size % batchSize]++;
17+
}
18+
int fromZero = withSize[0];
19+
withSize[0] = 0;
20+
int fromEnds = 0;
21+
for (int l = 1, r = batchSize - 1; l < r; l++, r--) {
22+
int usable = Math.min(withSize[l], withSize[r]);
23+
fromEnds += usable;
24+
withSize[l] -= usable;
25+
withSize[r] -= usable;
2926
}
30-
res += dfs(0, remGroup, count, batchSize);
31-
return res;
27+
int fromMid = 0;
28+
if (batchSize % 2 == 0) {
29+
fromMid = withSize[batchSize / 2] / 2;
30+
withSize[batchSize / 2] -= fromMid * 2;
31+
}
32+
return get(pruneEnd(withSize), batchSize, 0, new HashMap<>())
33+
+ fromZero
34+
+ fromEnds
35+
+ fromMid;
3236
}
3337

34-
private int dfs(int curr, int remain, int[] count, int batch) {
35-
if (remain == 0) {
36-
return 0;
38+
private int get(int[] ar, int batchSize, int rem, Map<Long, Integer> cache) {
39+
long hash = 0;
40+
for (int e : ar) {
41+
hash = hash * 69l + e;
3742
}
38-
int res = 0;
39-
String s = Arrays.toString(count);
40-
if (MAP.containsKey(s)) {
41-
return MAP.get(s);
43+
Integer fromCache = cache.get(hash);
44+
if (fromCache != null) {
45+
return fromCache;
4246
}
43-
if (curr == 0) {
44-
res++;
45-
curr = batch;
47+
if (zeroed(ar)) {
48+
cache.put(hash, 0);
49+
return 0;
4650
}
47-
int val = 0;
48-
for (int i = 1; i < count.length; i++) {
49-
if (count[i] == 0) {
51+
int max = 0;
52+
for (int i = 0; i < ar.length; i++) {
53+
if (ar[i] == 0) {
5054
continue;
5155
}
52-
count[i]--;
53-
val = Math.max(val, dfs((curr - i + batch) % batch, remain - 1, count, batch));
54-
count[i]++;
56+
ar[i]--;
57+
int from = get(ar, batchSize, (rem + i) % batchSize, cache);
58+
if (from > max) {
59+
max = from;
60+
}
61+
ar[i]++;
5562
}
56-
res += val;
57-
MAP.put(s, res);
58-
return res;
63+
int score = max + (rem == 0 ? 1 : 0);
64+
cache.put(hash, score);
65+
return score;
66+
}
67+
68+
private int[] pruneEnd(int[] in) {
69+
int endingZeros = 0;
70+
for (int i = in.length - 1; i >= 0; i--) {
71+
if (in[i] != 0) {
72+
break;
73+
}
74+
endingZeros++;
75+
}
76+
int[] out = new int[in.length - endingZeros];
77+
for (int i = 0; i < out.length; i++) {
78+
out[i] = in[i];
79+
}
80+
return out;
81+
}
82+
83+
private boolean zeroed(int[] ar) {
84+
for (int e : ar)
85+
if (e != 0) {
86+
return false;
87+
}
88+
return true;
5989
}
6090
}

0 commit comments

Comments
 (0)