From c91d46e22655d63263b0ed09912c442a2bb82685 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 21 Feb 2025 02:16:52 +0200 Subject: [PATCH 1/6] Improved task 1815 --- .../Solution.java | 110 +++++++++++------- 1 file changed, 70 insertions(+), 40 deletions(-) diff --git a/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java b/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java index 8060c27df..31414559f 100644 --- a/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java +++ b/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java @@ -1,60 +1,90 @@ package g1801_1900.s1815_maximum_number_of_groups_getting_fresh_donuts; // #Hard #Array #Dynamic_Programming #Bit_Manipulation #Bitmask #Memoization -// #2022_05_03_Time_7_ms_(86.67%)_Space_43.6_MB_(73.33%) +// #2025_02_21_Time_2_ms_(100.00%)_Space_41.56_MB_(100.00%) -import java.util.Arrays; import java.util.HashMap; import java.util.Map; public class Solution { - private static final Map MAP = new HashMap<>(); - public int maxHappyGroups(int batchSize, int[] groups) { - int[] count = new int[batchSize]; - int res = 0; - int remGroup = 0; - for (int group : groups) { - int g = group % batchSize; - if (g == 0) { - res++; - } else if (count[batchSize - g] > 0) { - remGroup--; - res++; - count[batchSize - g]--; - } else { - count[g]++; - remGroup++; - } + if (batchSize == 1) { + return groups.length; + } + int[] withSize = new int[batchSize]; + for (int size : groups) { + withSize[size % batchSize]++; + } + int fromZero = withSize[0]; + withSize[0] = 0; + int fromEnds = 0; + for (int l = 1, r = batchSize - 1; l < r; l++, r--) { + int usable = Math.min(withSize[l], withSize[r]); + fromEnds += usable; + withSize[l] -= usable; + withSize[r] -= usable; } - res += dfs(0, remGroup, count, batchSize); - return res; + int fromMid = 0; + if (batchSize % 2 == 0) { + fromMid = withSize[batchSize / 2] / 2; + withSize[batchSize / 2] -= fromMid * 2; + } + return get(pruneEnd(withSize), batchSize, 0, new HashMap<>()) + + fromZero + + fromEnds + + fromMid; } - private int dfs(int curr, int remain, int[] count, int batch) { - if (remain == 0) { - return 0; + private int get(int[] ar, int batchSize, int rem, Map cache) { + long hash = 0; + for (int e : ar) { + hash = hash * 69l + e; } - int res = 0; - String s = Arrays.toString(count); - if (MAP.containsKey(s)) { - return MAP.get(s); + Integer fromCache = cache.get(hash); + if (fromCache != null) { + return fromCache; } - if (curr == 0) { - res++; - curr = batch; + if (zeroed(ar)) { + cache.put(hash, 0); + return 0; } - int val = 0; - for (int i = 1; i < count.length; i++) { - if (count[i] == 0) { + int max = 0; + for (int i = 0; i < ar.length; i++) { + if (ar[i] == 0) { continue; } - count[i]--; - val = Math.max(val, dfs((curr - i + batch) % batch, remain - 1, count, batch)); - count[i]++; + ar[i]--; + int from = get(ar, batchSize, (rem + i) % batchSize, cache); + if (from > max) { + max = from; + } + ar[i]++; } - res += val; - MAP.put(s, res); - return res; + int score = max + (rem == 0 ? 1 : 0); + cache.put(hash, score); + return score; + } + + private int[] pruneEnd(int[] in) { + int endingZeros = 0; + for (int i = in.length - 1; i >= 0; i--) { + if (in[i] != 0) { + break; + } + endingZeros++; + } + int[] out = new int[in.length - endingZeros]; + for (int i = 0; i < out.length; i++) { + out[i] = in[i]; + } + return out; + } + + private boolean zeroed(int[] ar) { + for (int e : ar) + if (e != 0) { + return false; + } + return true; } } From c9baa7ada558fad0804818e6898925319fde6417 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 21 Feb 2025 02:19:02 +0200 Subject: [PATCH 2/6] Fixed format --- .../Solution.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java b/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java index 31414559f..01f7ee3dc 100644 --- a/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java +++ b/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java @@ -81,10 +81,11 @@ private int[] pruneEnd(int[] in) { } private boolean zeroed(int[] ar) { - for (int e : ar) + for (int e : ar) { if (e != 0) { return false; } + } return true; } } From 82ede65e646b65c36a629aed10eb00e73cc727e1 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 21 Feb 2025 02:20:32 +0200 Subject: [PATCH 3/6] Fixed format --- .../Solution.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java b/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java index 01f7ee3dc..12b5cf05b 100644 --- a/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java +++ b/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java @@ -38,7 +38,7 @@ public int maxHappyGroups(int batchSize, int[] groups) { private int get(int[] ar, int batchSize, int rem, Map cache) { long hash = 0; for (int e : ar) { - hash = hash * 69l + e; + hash = hash * 69L + e; } Integer fromCache = cache.get(hash); if (fromCache != null) { From c5d4d4b6234f1af9de9acf957f360315a5e15c71 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 21 Feb 2025 02:23:37 +0200 Subject: [PATCH 4/6] Fixed sonar --- .../Solution.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java b/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java index 12b5cf05b..adf572e28 100644 --- a/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java +++ b/src/main/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/Solution.java @@ -74,9 +74,7 @@ private int[] pruneEnd(int[] in) { endingZeros++; } int[] out = new int[in.length - endingZeros]; - for (int i = 0; i < out.length; i++) { - out[i] = in[i]; - } + System.arraycopy(in, 0, out, 0, out.length); return out; } From c0222202b4860fdde1ce6db4f0a8678817bc99b0 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 21 Feb 2025 02:28:50 +0200 Subject: [PATCH 5/6] Added tests --- .../SolutionTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/test/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/SolutionTest.java b/src/test/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/SolutionTest.java index 2c140d800..f13b2b85a 100644 --- a/src/test/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/SolutionTest.java +++ b/src/test/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/SolutionTest.java @@ -16,4 +16,31 @@ void maxHappyGroups2() { assertThat( new Solution().maxHappyGroups(4, new int[] {1, 3, 2, 5, 2, 2, 1, 6}), equalTo(4)); } + + @Test + void maxHappyGroups3() { + assertThat( + new Solution() + .maxHappyGroups( + 7, + new int[] { + 287773481, 815094798, 356732984, 644469322, 543193620, + 903158817, 274116865, 395252956, 363839119, 365378492, + 122313059, 312690039, 252532812 + }), + equalTo(9)); + } + + @Test + void maxHappyGroups4() { + assertThat( + new Solution() + .maxHappyGroups( + 9, + new int[] { + 3, 1, 3, 3, 5, 6, 1, 1, 9, 10, 3, 3, 3, 1, 1, 3, 3, 3, 19, 20, + 1, 3, 3, 3, 3, 1, 1, 3, 3, 30 + }), + equalTo(9)); + } } From 1f08cc492065286e792fe2eb0c210c3468a37d73 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 21 Feb 2025 02:30:29 +0200 Subject: [PATCH 6/6] Added test --- .../SolutionTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/SolutionTest.java b/src/test/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/SolutionTest.java index f13b2b85a..7bd950983 100644 --- a/src/test/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/SolutionTest.java +++ b/src/test/java/g1801_1900/s1815_maximum_number_of_groups_getting_fresh_donuts/SolutionTest.java @@ -43,4 +43,9 @@ void maxHappyGroups4() { }), equalTo(9)); } + + @Test + void maxHappyGroups5() { + assertThat(new Solution().maxHappyGroups(1, new int[] {1, 2, 3}), equalTo(3)); + } }