From 892e1f82b166f24cf9aef6a9e972fb5b3a111ce9 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 23 Feb 2025 08:42:09 +0200 Subject: [PATCH 1/9] Added tasks 3461-3464 --- .../Solution.java | 19 ++++ .../readme.md | 49 +++++++++ .../Solution.java | 34 ++++++ .../readme.md | 42 ++++++++ .../Solution.java | 49 +++++++++ .../readme.md | 49 +++++++++ .../Solution.java | 101 ++++++++++++++++++ .../readme.md | 59 ++++++++++ .../SolutionTest.java | 18 ++++ .../SolutionTest.java | 22 ++++ .../SolutionTest.java | 18 ++++ .../SolutionTest.java | 36 +++++++ 12 files changed, 496 insertions(+) create mode 100644 src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/Solution.java create mode 100644 src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/readme.md create mode 100644 src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/Solution.java create mode 100644 src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/readme.md create mode 100644 src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/Solution.java create mode 100644 src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/readme.md create mode 100644 src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java create mode 100644 src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/readme.md create mode 100644 src/test/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/SolutionTest.java create mode 100644 src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java create mode 100644 src/test/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/SolutionTest.java create mode 100644 src/test/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/SolutionTest.java diff --git a/src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/Solution.java b/src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/Solution.java new file mode 100644 index 000000000..6905158ca --- /dev/null +++ b/src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/Solution.java @@ -0,0 +1,19 @@ +package g3401_3500.s3461_check_if_digits_are_equal_in_string_after_operations_i; + +// #Easy #2025_02_23_Time_23_ms_(100.00%)_Space_45.51_MB_(100.00%) + +public class Solution { + public boolean hasSameDigits(String s) { + int n = s.length(); + while (n > 2) { + StringBuilder nstr = new StringBuilder(); + for (int i = 1; i < n; i++) { + int next = ((s.charAt(i) - '0') + (s.charAt(i - 1) - '0')) % 10; + nstr.append(next); + } + n--; + s = nstr.toString(); + } + return s.charAt(0) == s.charAt(1); + } +} diff --git a/src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/readme.md b/src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/readme.md new file mode 100644 index 000000000..b8b26aabc --- /dev/null +++ b/src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/readme.md @@ -0,0 +1,49 @@ +3461\. Check If Digits Are Equal in String After Operations I + +Easy + +You are given a string `s` consisting of digits. Perform the following operation repeatedly until the string has **exactly** two digits: + +* For each pair of consecutive digits in `s`, starting from the first digit, calculate a new digit as the sum of the two digits **modulo** 10. +* Replace `s` with the sequence of newly calculated digits, _maintaining the order_ in which they are computed. + +Return `true` if the final two digits in `s` are the **same**; otherwise, return `false`. + +**Example 1:** + +**Input:** s = "3902" + +**Output:** true + +**Explanation:** + +* Initially, `s = "3902"` +* First operation: + * `(s[0] + s[1]) % 10 = (3 + 9) % 10 = 2` + * `(s[1] + s[2]) % 10 = (9 + 0) % 10 = 9` + * `(s[2] + s[3]) % 10 = (0 + 2) % 10 = 2` + * `s` becomes `"292"` +* Second operation: + * `(s[0] + s[1]) % 10 = (2 + 9) % 10 = 1` + * `(s[1] + s[2]) % 10 = (9 + 2) % 10 = 1` + * `s` becomes `"11"` +* Since the digits in `"11"` are the same, the output is `true`. + +**Example 2:** + +**Input:** s = "34789" + +**Output:** false + +**Explanation:** + +* Initially, `s = "34789"`. +* After the first operation, `s = "7157"`. +* After the second operation, `s = "862"`. +* After the third operation, `s = "48"`. +* Since `'4' != '8'`, the output is `false`. + +**Constraints:** + +* `3 <= s.length <= 100` +* `s` consists of only digits. \ No newline at end of file diff --git a/src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/Solution.java b/src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/Solution.java new file mode 100644 index 000000000..872cd1124 --- /dev/null +++ b/src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/Solution.java @@ -0,0 +1,34 @@ +package g3401_3500.s3462_maximum_sum_with_at_most_k_elements; + +// #Medium #2025_02_23_Time_278_ms_(_%)_Space_73.54_MB_(_%) + +import java.util.Collections; +import java.util.PriorityQueue; + +public class Solution { + public long maxSum(int[][] grid, int[] limits, int k) { + if (grid.length == 0) { + return 0; + } + PriorityQueue pq = new PriorityQueue<>(Collections.reverseOrder()); + PriorityQueue temp; + for (int i = 0; i < grid.length; i++) { + temp = new PriorityQueue<>(Collections.reverseOrder()); + for (int j = 0; j < grid[i].length; j++) { + temp.add(grid[i][j]); + } + int cnt = 0; + while (!temp.isEmpty() && cnt < limits[i]) { + pq.add(temp.poll()); + cnt += 1; + } + } + long result = 0; + long count = 0; + while (!pq.isEmpty() && count < k) { + result += pq.poll(); + count += 1; + } + return result; + } +} diff --git a/src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/readme.md b/src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/readme.md new file mode 100644 index 000000000..4b9177359 --- /dev/null +++ b/src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/readme.md @@ -0,0 +1,42 @@ +3462\. Maximum Sum With at Most K Elements + +Medium + +You are given a 2D integer matrix `grid` of size `n x m`, an integer array `limits` of length `n`, and an integer `k`. The task is to find the **maximum sum** of **at most** `k` elements from the matrix `grid` such that: + +* The number of elements taken from the ith row of `grid` does not exceed `limits[i]`. + + +Return the **maximum sum**. + +**Example 1:** + +**Input:** grid = [[1,2],[3,4]], limits = [1,2], k = 2 + +**Output:** 7 + +**Explanation:** + +* From the second row, we can take at most 2 elements. The elements taken are 4 and 3. +* The maximum possible sum of at most 2 selected elements is `4 + 3 = 7`. + +**Example 2:** + +**Input:** grid = [[5,3,7],[8,2,6]], limits = [2,2], k = 3 + +**Output:** 21 + +**Explanation:** + +* From the first row, we can take at most 2 elements. The element taken is 7. +* From the second row, we can take at most 2 elements. The elements taken are 8 and 6. +* The maximum possible sum of at most 3 selected elements is `7 + 8 + 6 = 21`. + +**Constraints:** + +* `n == grid.length == limits.length` +* `m == grid[i].length` +* `1 <= n, m <= 500` +* 0 <= grid[i][j] <= 105 +* `0 <= limits[i] <= m` +* `0 <= k <= min(n * m, sum(limits))` \ No newline at end of file diff --git a/src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/Solution.java b/src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/Solution.java new file mode 100644 index 000000000..a419c8f0f --- /dev/null +++ b/src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/Solution.java @@ -0,0 +1,49 @@ +package g3401_3500.s3463_check_if_digits_are_equal_in_string_after_operations_ii; + +// #Hard #2025_02_23_Time_103_ms_(100.00%)_Space_45.58_MB_(100.00%) + +public class Solution { + public boolean hasSameDigits(String s) { + int n = s.length(); + int nMunus2 = n - 2; + int f0 = 0; + int f1 = 0; + for (int j = 0; j <= nMunus2; j++) { + int c = binomMod10(nMunus2, j); + f0 = (f0 + c * (s.charAt(j) - '0')) % 10; + f1 = (f1 + c * (s.charAt(j + 1) - '0')) % 10; + } + return f0 == f1; + } + + private int binomMod10(int n, int k) { + int r2 = binomMod2(n, k); + int r5 = binomMod5(n, k); + for (int x = 0; x < 10; x++) { + if (x % 2 == r2 && x % 5 == r5) { + return x; + } + } + return 0; + } + + private int binomMod2(int n, int k) { + return ((n & k) == k) ? 1 : 0; + } + + private int binomMod5(int n, int k) { + int[][] t = {{1}, {1, 1}, {1, 2, 1}, {1, 3, 3, 1}, {1, 4, 1, 4, 1}}; + int res = 1; + while (n > 0 || k > 0) { + int nd = n % 5; + int kd = k % 5; + if (kd > nd) { + return 0; + } + res = (res * t[nd][kd]) % 5; + n /= 5; + k /= 5; + } + return res; + } +} diff --git a/src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/readme.md b/src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/readme.md new file mode 100644 index 000000000..fe4e2de15 --- /dev/null +++ b/src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/readme.md @@ -0,0 +1,49 @@ +3463\. Check If Digits Are Equal in String After Operations II + +Hard + +You are given a string `s` consisting of digits. Perform the following operation repeatedly until the string has **exactly** two digits: + +* For each pair of consecutive digits in `s`, starting from the first digit, calculate a new digit as the sum of the two digits **modulo** 10. +* Replace `s` with the sequence of newly calculated digits, _maintaining the order_ in which they are computed. + +Return `true` if the final two digits in `s` are the **same**; otherwise, return `false`. + +**Example 1:** + +**Input:** s = "3902" + +**Output:** true + +**Explanation:** + +* Initially, `s = "3902"` +* First operation: + * `(s[0] + s[1]) % 10 = (3 + 9) % 10 = 2` + * `(s[1] + s[2]) % 10 = (9 + 0) % 10 = 9` + * `(s[2] + s[3]) % 10 = (0 + 2) % 10 = 2` + * `s` becomes `"292"` +* Second operation: + * `(s[0] + s[1]) % 10 = (2 + 9) % 10 = 1` + * `(s[1] + s[2]) % 10 = (9 + 2) % 10 = 1` + * `s` becomes `"11"` +* Since the digits in `"11"` are the same, the output is `true`. + +**Example 2:** + +**Input:** s = "34789" + +**Output:** false + +**Explanation:** + +* Initially, `s = "34789"`. +* After the first operation, `s = "7157"`. +* After the second operation, `s = "862"`. +* After the third operation, `s = "48"`. +* Since `'4' != '8'`, the output is `false`. + +**Constraints:** + +* 3 <= s.length <= 105 +* `s` consists of only digits. \ No newline at end of file diff --git a/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java b/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java new file mode 100644 index 000000000..a8a64b3a8 --- /dev/null +++ b/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java @@ -0,0 +1,101 @@ +package g3401_3500.s3464_maximize_the_distance_between_points_on_a_square; + +// #Hard #2025_02_23_Time_222_ms_(100.00%)_Space_52.33_MB_(100.00%) + +import java.util.Arrays; + +public class Solution { + public int maxDistance(int sideLength, int[][] points, int requiredPoints) { + long perimeter = 4L * sideLength; + int numPoints = points.length; + long[] mappedPositions = new long[numPoints]; + for (int i = 0; i < numPoints; i++) { + mappedPositions[i] = mapToPerimeter(sideLength, points[i][0], points[i][1]); + } + Arrays.sort(mappedPositions); + long low = 0; + long high = perimeter; + while (low < high) { + long mid = (low + high + 1) / 2; + if (isValidDistance(mid, requiredPoints, mappedPositions, perimeter)) { + low = mid; + } else { + high = mid - 1; + } + } + return (int) low; + } + + private long mapToPerimeter(int sideLength, int x, int y) { + if (y == sideLength) { + return x; + } + if (x == sideLength) { + return sideLength + (sideLength - y); + } + if (y == 0) { + return 2L * sideLength + (sideLength - x); + } + return 3L * sideLength + y; + } + + private boolean isValidDistance( + long minDistance, int requiredPoints, long[] mappedPositions, long perimeter) { + int numPoints = mappedPositions.length; + long[] extendedPositions = new long[2 * numPoints]; + for (int i = 0; i < numPoints; i++) { + extendedPositions[i] = mappedPositions[i]; + extendedPositions[i + numPoints] = mappedPositions[i] + perimeter; + } + for (int i = 0; i < numPoints; i++) { + if (canSelectRequiredPoints( + i, + minDistance, + requiredPoints, + mappedPositions, + extendedPositions, + perimeter)) { + return true; + } + } + return false; + } + + private boolean canSelectRequiredPoints( + int startIndex, + long minDistance, + int requiredPoints, + long[] mappedPositions, + long[] extendedPositions, + long perimeter) { + int selectedCount = 1; + long previousPosition = mappedPositions[startIndex]; + int currentIndex = startIndex; + for (int i = 1; i < requiredPoints; i++) { + long targetPosition = previousPosition + minDistance; + int left = currentIndex + 1; + int right = startIndex + mappedPositions.length; + int nextIndex = lowerBound(extendedPositions, left, right, targetPosition); + if (nextIndex >= right) { + return false; + } + selectedCount++; + previousPosition = extendedPositions[nextIndex]; + currentIndex = nextIndex; + } + return selectedCount == requiredPoints + && (previousPosition - mappedPositions[startIndex] <= perimeter - minDistance); + } + + private int lowerBound(long[] arr, int left, int right, long target) { + while (left < right) { + int mid = left + (right - left) / 2; + if (arr[mid] >= target) { + right = mid; + } else { + left = mid + 1; + } + } + return left; + } +} diff --git a/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/readme.md b/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/readme.md new file mode 100644 index 000000000..2fc14a006 --- /dev/null +++ b/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/readme.md @@ -0,0 +1,59 @@ +3464\. Maximize the Distance Between Points on a Square + +Hard + +You are given an integer `side`, representing the edge length of a square with corners at `(0, 0)`, `(0, side)`, `(side, 0)`, and `(side, side)` on a Cartesian plane. + +You are also given a **positive** integer `k` and a 2D integer array `points`, where points[i] = [xi, yi] represents the coordinate of a point lying on the **boundary** of the square. + +You need to select `k` elements among `points` such that the **minimum** Manhattan distance between any two points is **maximized**. + +Return the **maximum** possible **minimum** Manhattan distance between the selected `k` points. + +The Manhattan Distance between two cells (xi, yi) and (xj, yj) is |xi - xj| + |yi - yj|. + +**Example 1:** + +**Input:** side = 2, points = [[0,2],[2,0],[2,2],[0,0]], k = 4 + +**Output:** 2 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/01/28/4080_example0_revised.png) + +Select all four points. + +**Example 2:** + +**Input:** side = 2, points = [[0,0],[1,2],[2,0],[2,2],[2,1]], k = 4 + +**Output:** 1 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/01/28/4080_example1_revised.png) + +Select the points `(0, 0)`, `(2, 0)`, `(2, 2)`, and `(2, 1)`. + +**Example 3:** + +**Input:** side = 2, points = [[0,0],[0,1],[0,2],[1,2],[2,0],[2,2],[2,1]], k = 5 + +**Output:** 1 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/01/28/4080_example2_revised.png) + +Select the points `(0, 0)`, `(0, 1)`, `(0, 2)`, `(1, 2)`, and `(2, 2)`. + +**Constraints:** + +* 1 <= side <= 109 +* 4 <= points.length <= min(4 * side, 15 * 103) +* `points[i] == [xi, yi]` +* The input is generated such that: + * `points[i]` lies on the boundary of the square. + * All `points[i]` are **unique**. +* `4 <= k <= min(25, points.length)` \ No newline at end of file diff --git a/src/test/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/SolutionTest.java b/src/test/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/SolutionTest.java new file mode 100644 index 000000000..3156aa652 --- /dev/null +++ b/src/test/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/SolutionTest.java @@ -0,0 +1,18 @@ +package g3401_3500.s3461_check_if_digits_are_equal_in_string_after_operations_i; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void hasSameDigits() { + assertThat(new Solution().hasSameDigits("3902"), equalTo(true)); + } + + @Test + void hasSameDigits2() { + assertThat(new Solution().hasSameDigits("34789"), equalTo(false)); + } +} diff --git a/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java b/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java new file mode 100644 index 000000000..612d7edeb --- /dev/null +++ b/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java @@ -0,0 +1,22 @@ +package g3401_3500.s3462_maximum_sum_with_at_most_k_elements; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxSum() { + assertThat( + new Solution().maxSum(new int[][] {{1, 2}, {3, 4}}, new int[] {1, 2}, 2), + equalTo(7L)); + } + + @Test + void maxSum2() { + assertThat( + new Solution().maxSum(new int[][] {{5, 3, 7}, {8, 2, 6}}, new int[] {2, 2}, 3), + equalTo(21L)); + } +} diff --git a/src/test/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/SolutionTest.java b/src/test/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/SolutionTest.java new file mode 100644 index 000000000..b650ac1ed --- /dev/null +++ b/src/test/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/SolutionTest.java @@ -0,0 +1,18 @@ +package g3401_3500.s3463_check_if_digits_are_equal_in_string_after_operations_ii; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void hasSameDigits() { + assertThat(new Solution().hasSameDigits("3902"), equalTo(true)); + } + + @Test + void hasSameDigits2() { + assertThat(new Solution().hasSameDigits("34789"), equalTo(false)); + } +} diff --git a/src/test/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/SolutionTest.java b/src/test/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/SolutionTest.java new file mode 100644 index 000000000..a7b779b2d --- /dev/null +++ b/src/test/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/SolutionTest.java @@ -0,0 +1,36 @@ +package g3401_3500.s3464_maximize_the_distance_between_points_on_a_square; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxDistance() { + assertThat( + new Solution().maxDistance(2, new int[][] {{0, 2}, {2, 0}, {2, 2}, {0, 0}}, 4), + equalTo(2)); + } + + @Test + void maxDistance2() { + assertThat( + new Solution() + .maxDistance(2, new int[][] {{0, 0}, {1, 2}, {2, 0}, {2, 2}, {2, 1}}, 4), + equalTo(1)); + } + + @Test + void maxDistance3() { + assertThat( + new Solution() + .maxDistance( + 2, + new int[][] { + {0, 0}, {0, 1}, {0, 2}, {1, 2}, {2, 0}, {2, 2}, {2, 1} + }, + 5), + equalTo(1)); + } +} From bef849363e3eb8a0533c99b41b59d1a63da5b930 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 23 Feb 2025 08:47:12 +0200 Subject: [PATCH 2/9] Fixed sonar --- .../Solution.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java b/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java index a8a64b3a8..93abf5110 100644 --- a/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java +++ b/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java @@ -31,7 +31,7 @@ private long mapToPerimeter(int sideLength, int x, int y) { return x; } if (x == sideLength) { - return sideLength + (sideLength - y); + return sideLength + (long) (sideLength - y); } if (y == 0) { return 2L * sideLength + (sideLength - x); From 051299f0c0efa9fa297f78b7b2088f4f23b94c7c Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 23 Feb 2025 08:49:35 +0200 Subject: [PATCH 3/9] Added test --- .../SolutionTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/SolutionTest.java b/src/test/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/SolutionTest.java index b650ac1ed..af841e49f 100644 --- a/src/test/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/SolutionTest.java +++ b/src/test/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/SolutionTest.java @@ -15,4 +15,9 @@ void hasSameDigits() { void hasSameDigits2() { assertThat(new Solution().hasSameDigits("34789"), equalTo(false)); } + + @Test + void hasSameDigits3() { + assertThat(new Solution().hasSameDigits("3506677"), equalTo(false)); + } } From e1b9123df9544279fa202bac3717c885b1b5f19c Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 23 Feb 2025 08:55:16 +0200 Subject: [PATCH 4/9] Added test --- .../SolutionTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java b/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java index 612d7edeb..3495c2ce1 100644 --- a/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java +++ b/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java @@ -19,4 +19,11 @@ void maxSum2() { new Solution().maxSum(new int[][] {{5, 3, 7}, {8, 2, 6}}, new int[] {2, 2}, 3), equalTo(21L)); } + + @Test + void maxSum3() { + assertThat( + new Solution().maxSum(new int[][] {{}}, new int[] {2, 2}, 3), + equalTo(0L)); + } } From c672956ae281f807b9bc7b717fdbfaa1914a4542 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 23 Feb 2025 08:58:17 +0200 Subject: [PATCH 5/9] Fixed format --- .../SolutionTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java b/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java index 3495c2ce1..1f58f14e7 100644 --- a/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java +++ b/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java @@ -22,8 +22,6 @@ void maxSum2() { @Test void maxSum3() { - assertThat( - new Solution().maxSum(new int[][] {{}}, new int[] {2, 2}, 3), - equalTo(0L)); + assertThat(new Solution().maxSum(new int[][] {{}}, new int[] {2, 2}, 3), equalTo(0L)); } } From a35a91d7904d30aa2a0d79a9d7ecbfa2f5b7eb69 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 23 Feb 2025 09:04:39 +0200 Subject: [PATCH 6/9] Improved test --- .../s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java b/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java index 1f58f14e7..279e111dd 100644 --- a/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java +++ b/src/test/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/SolutionTest.java @@ -22,6 +22,6 @@ void maxSum2() { @Test void maxSum3() { - assertThat(new Solution().maxSum(new int[][] {{}}, new int[] {2, 2}, 3), equalTo(0L)); + assertThat(new Solution().maxSum(new int[][] {}, new int[] {2, 2}, 3), equalTo(0L)); } } From 2615bc9ccb538b1c88a51513afc5fea8fe3d5854 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 25 Feb 2025 03:28:15 +0200 Subject: [PATCH 7/9] Improved solutions --- .../Solution.java | 23 +-- .../Solution.java | 39 +++-- .../Solution.java | 95 +++++++----- .../Solution.java | 140 ++++++++---------- 4 files changed, 149 insertions(+), 148 deletions(-) diff --git a/src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/Solution.java b/src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/Solution.java index 6905158ca..dd1a68170 100644 --- a/src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/Solution.java +++ b/src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/Solution.java @@ -1,19 +1,22 @@ package g3401_3500.s3461_check_if_digits_are_equal_in_string_after_operations_i; -// #Easy #2025_02_23_Time_23_ms_(100.00%)_Space_45.51_MB_(100.00%) +// #Easy #String #Math #Simulation #Number_Theory #Combinatorics +// #2025_02_25_Time_2_ms_(96.71%)_Space_42.26_MB_(97.03%) public class Solution { public boolean hasSameDigits(String s) { - int n = s.length(); - while (n > 2) { - StringBuilder nstr = new StringBuilder(); - for (int i = 1; i < n; i++) { - int next = ((s.charAt(i) - '0') + (s.charAt(i - 1) - '0')) % 10; - nstr.append(next); + char[] ch = s.toCharArray(); + int k = ch.length - 1; + while (k != 1) { + for (int i = 0; i < k; i++) { + int a = (int) ch[i] - 48; + int b = (int) ch[i + 1] - 48; + int d = (a + b) % 10; + char c = (char) (d + '0'); + ch[i] = c; } - n--; - s = nstr.toString(); + k--; } - return s.charAt(0) == s.charAt(1); + return ch[0] == ch[1]; } } diff --git a/src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/Solution.java b/src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/Solution.java index 872cd1124..6134fc58f 100644 --- a/src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/Solution.java +++ b/src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/Solution.java @@ -1,34 +1,29 @@ package g3401_3500.s3462_maximum_sum_with_at_most_k_elements; -// #Medium #2025_02_23_Time_278_ms_(_%)_Space_73.54_MB_(_%) - -import java.util.Collections; -import java.util.PriorityQueue; +// #Medium #Array #Sorting #Greedy #Matrix #Heap_(Priority_Queue) +// #2025_02_25_Time_62_ms_(99.82%)_Space_78.09_MB_(20.19%) public class Solution { public long maxSum(int[][] grid, int[] limits, int k) { - if (grid.length == 0) { - return 0; + int l = 0; + for (int i = 0; i < limits.length; i++) { + l += limits[i]; } - PriorityQueue pq = new PriorityQueue<>(Collections.reverseOrder()); - PriorityQueue temp; + int[] dp = new int[l]; + int a = 0; for (int i = 0; i < grid.length; i++) { - temp = new PriorityQueue<>(Collections.reverseOrder()); - for (int j = 0; j < grid[i].length; j++) { - temp.add(grid[i][j]); - } - int cnt = 0; - while (!temp.isEmpty() && cnt < limits[i]) { - pq.add(temp.poll()); - cnt += 1; + int lim = limits[i]; + Arrays.sort(grid[i]); + for (int j = grid[i].length - lim; j < grid[i].length; j++) { + dp[a] = grid[i][j]; + a++; } } - long result = 0; - long count = 0; - while (!pq.isEmpty() && count < k) { - result += pq.poll(); - count += 1; + Arrays.sort(dp); + long sum = 0L; + for (int i = l - 1; i >= l - k; i--) { + sum += dp[i]; } - return result; + return sum; } } diff --git a/src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/Solution.java b/src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/Solution.java index a419c8f0f..c31be6659 100644 --- a/src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/Solution.java +++ b/src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/Solution.java @@ -1,49 +1,74 @@ package g3401_3500.s3463_check_if_digits_are_equal_in_string_after_operations_ii; -// #Hard #2025_02_23_Time_103_ms_(100.00%)_Space_45.58_MB_(100.00%) +// #Hard #String #Math #Number_Theory #Combinatorics +// #2025_02_25_Time_43_ms_(99.64%)_Space_49.40_MB_(10.02%) public class Solution { - public boolean hasSameDigits(String s) { - int n = s.length(); - int nMunus2 = n - 2; - int f0 = 0; - int f1 = 0; - for (int j = 0; j <= nMunus2; j++) { - int c = binomMod10(nMunus2, j); - f0 = (f0 + c * (s.charAt(j) - '0')) % 10; - f1 = (f1 + c * (s.charAt(j + 1) - '0')) % 10; + private int powMod10(int a, int n) { + int x = 1; + while (n >= 1) { + if (n % 2 == 1) { + x = (x * a) % 10; + } + a = (a * a) % 10; + n /= 2; } - return f0 == f1; + return x; } - private int binomMod10(int n, int k) { - int r2 = binomMod2(n, k); - int r5 = binomMod5(n, k); - for (int x = 0; x < 10; x++) { - if (x % 2 == r2 && x % 5 == r5) { - return x; + private int[] f(int n) { + int[] ns = new int[n + 1]; + int[] n2 = new int[n + 1]; + int[] n5 = new int[n + 1]; + ns[0] = 1; + for (int i = 1; i <= n; ++i) { + int m = i; + n2[i] = n2[i - 1]; + n5[i] = n5[i - 1]; + while (m % 2 == 0) { + m /= 2; + n2[i]++; + } + while (m % 5 == 0) { + m /= 5; + n5[i]++; } + ns[i] = (ns[i - 1] * m) % 10; } - return 0; - } - - private int binomMod2(int n, int k) { - return ((n & k) == k) ? 1 : 0; + int[] inv = new int[10]; + for (int i = 1; i < 10; ++i) { + for (int j = 0; j < 10; ++j) { + if (i * j % 10 == 1) { + inv[i] = j; + } + } + } + int[] xs = new int[n + 1]; + for (int k = 0; k <= n; ++k) { + int a = 0; + int s2 = n2[n] - n2[n - k] - n2[k]; + int s5 = n5[n] - n5[n - k] - n5[k]; + if (s2 == 0 || s5 == 0) { + a = (ns[n] * inv[ns[n - k]] * inv[ns[k]] * powMod10(2, s2) * powMod10(5, s5)) % 10; + } + xs[k] = a; + } + return xs; } - private int binomMod5(int n, int k) { - int[][] t = {{1}, {1, 1}, {1, 2, 1}, {1, 3, 3, 1}, {1, 4, 1, 4, 1}}; - int res = 1; - while (n > 0 || k > 0) { - int nd = n % 5; - int kd = k % 5; - if (kd > nd) { - return 0; - } - res = (res * t[nd][kd]) % 5; - n /= 5; - k /= 5; + public boolean hasSameDigits(String s) { + int n = s.length(); + int[] xs = f(n - 2); + int[] arr = new int[n]; + for (int i = 0; i < n; i++) { + arr[i] = (int) (s.charAt(i) - '0'); + } + int num1 = 0; + int num2 = 0; + for (int i = 0; i < n - 1; i++) { + num1 = (num1 + xs[i] * arr[i]) % 10; + num2 = (num2 + xs[i] * arr[i + 1]) % 10; } - return res; + return num1 == num2; } } diff --git a/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java b/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java index 93abf5110..82f2d6709 100644 --- a/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java +++ b/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java @@ -1,101 +1,79 @@ package g3401_3500.s3464_maximize_the_distance_between_points_on_a_square; -// #Hard #2025_02_23_Time_222_ms_(100.00%)_Space_52.33_MB_(100.00%) +// #Hard #Array #Greedy #Binary_Search #2025_02_25_Time_18_ms_(98.51%)_Space_49.78_MB_(46.27%) import java.util.Arrays; public class Solution { - public int maxDistance(int sideLength, int[][] points, int requiredPoints) { - long perimeter = 4L * sideLength; - int numPoints = points.length; - long[] mappedPositions = new long[numPoints]; - for (int i = 0; i < numPoints; i++) { - mappedPositions[i] = mapToPerimeter(sideLength, points[i][0], points[i][1]); - } - Arrays.sort(mappedPositions); - long low = 0; - long high = perimeter; - while (low < high) { - long mid = (low + high + 1) / 2; - if (isValidDistance(mid, requiredPoints, mappedPositions, perimeter)) { - low = mid; + public int maxDistance(int side, int[][] pts, int k) { + int n = pts.length; + long[] p = new long[n]; + for (int i = 0; i < n; i++) { + int x = pts[i][0]; + int y = pts[i][1]; + long c; + if (y == 0) { + c = x; + } else if (x == side) { + c = side + y; + } else if (y == side) { + c = 2L * side + (side - x); } else { - high = mid - 1; + c = 3L * side + (side - y); } + p[i] = c; } - return (int) low; - } - - private long mapToPerimeter(int sideLength, int x, int y) { - if (y == sideLength) { - return x; - } - if (x == sideLength) { - return sideLength + (long) (sideLength - y); - } - if (y == 0) { - return 2L * sideLength + (sideLength - x); + Arrays.sort(p); + long c = 4L * side; + int tot = 2 * n; + long[] dArr = new long[tot]; + for (int i = 0; i < n; i++) { + dArr[i] = p[i]; + dArr[i + n] = p[i] + c; } - return 3L * sideLength + y; - } - - private boolean isValidDistance( - long minDistance, int requiredPoints, long[] mappedPositions, long perimeter) { - int numPoints = mappedPositions.length; - long[] extendedPositions = new long[2 * numPoints]; - for (int i = 0; i < numPoints; i++) { - extendedPositions[i] = mappedPositions[i]; - extendedPositions[i + numPoints] = mappedPositions[i] + perimeter; - } - for (int i = 0; i < numPoints; i++) { - if (canSelectRequiredPoints( - i, - minDistance, - requiredPoints, - mappedPositions, - extendedPositions, - perimeter)) { - return true; + int lo = 0; + int hi = 2 * side; + int ans = 0; + while (lo <= hi) { + int mid = (lo + hi) >>> 1; + if (check(mid, dArr, n, k, c)) { + ans = mid; + lo = mid + 1; + } else { + hi = mid - 1; } } - return false; + return ans; } - private boolean canSelectRequiredPoints( - int startIndex, - long minDistance, - int requiredPoints, - long[] mappedPositions, - long[] extendedPositions, - long perimeter) { - int selectedCount = 1; - long previousPosition = mappedPositions[startIndex]; - int currentIndex = startIndex; - for (int i = 1; i < requiredPoints; i++) { - long targetPosition = previousPosition + minDistance; - int left = currentIndex + 1; - int right = startIndex + mappedPositions.length; - int nextIndex = lowerBound(extendedPositions, left, right, targetPosition); - if (nextIndex >= right) { - return false; + private boolean check(int d, long[] dArr, int n, int k, long c) { + int len = dArr.length; + int[] nxt = new int[len]; + int j = 0; + for (int i = 0; i < len; i++) { + if (j < i + 1) { + j = i + 1; + } + while (j < len && dArr[j] < dArr[i] + d) { + j++; } - selectedCount++; - previousPosition = extendedPositions[nextIndex]; - currentIndex = nextIndex; + nxt[i] = (j < len) ? j : -1; } - return selectedCount == requiredPoints - && (previousPosition - mappedPositions[startIndex] <= perimeter - minDistance); - } - - private int lowerBound(long[] arr, int left, int right, long target) { - while (left < right) { - int mid = left + (right - left) / 2; - if (arr[mid] >= target) { - right = mid; - } else { - left = mid + 1; + for (int i = 0; i < n; i++) { + int cnt = 1; + int cur = i; + while (cnt < k) { + int nx = nxt[cur]; + if (nx == -1 || nx >= i + n) { + break; + } + cur = nx; + cnt++; + } + if (cnt == k && (dArr[i] + c - dArr[cur]) >= d) { + return true; } } - return left; + return false; } } From fd9f66d02600676f4686edafc29e993e178b841d Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 25 Feb 2025 03:30:24 +0200 Subject: [PATCH 8/9] Fixed compile --- .../s3462_maximum_sum_with_at_most_k_elements/Solution.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/Solution.java b/src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/Solution.java index 6134fc58f..84b16cf91 100644 --- a/src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/Solution.java +++ b/src/main/java/g3401_3500/s3462_maximum_sum_with_at_most_k_elements/Solution.java @@ -3,6 +3,8 @@ // #Medium #Array #Sorting #Greedy #Matrix #Heap_(Priority_Queue) // #2025_02_25_Time_62_ms_(99.82%)_Space_78.09_MB_(20.19%) +import java.util.Arrays; + public class Solution { public long maxSum(int[][] grid, int[] limits, int k) { int l = 0; From 2b9a4051f710809d0e7d7728e91477197e71e93b Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 25 Feb 2025 03:35:12 +0200 Subject: [PATCH 9/9] Fixed sonar --- .../Solution.java | 4 ++-- .../Solution.java | 2 +- .../Solution.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/Solution.java b/src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/Solution.java index dd1a68170..c6f46c4e4 100644 --- a/src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/Solution.java +++ b/src/main/java/g3401_3500/s3461_check_if_digits_are_equal_in_string_after_operations_i/Solution.java @@ -9,8 +9,8 @@ public boolean hasSameDigits(String s) { int k = ch.length - 1; while (k != 1) { for (int i = 0; i < k; i++) { - int a = (int) ch[i] - 48; - int b = (int) ch[i + 1] - 48; + int a = ch[i] - 48; + int b = ch[i + 1] - 48; int d = (a + b) % 10; char c = (char) (d + '0'); ch[i] = c; diff --git a/src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/Solution.java b/src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/Solution.java index c31be6659..ef3671d56 100644 --- a/src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/Solution.java +++ b/src/main/java/g3401_3500/s3463_check_if_digits_are_equal_in_string_after_operations_ii/Solution.java @@ -61,7 +61,7 @@ public boolean hasSameDigits(String s) { int[] xs = f(n - 2); int[] arr = new int[n]; for (int i = 0; i < n; i++) { - arr[i] = (int) (s.charAt(i) - '0'); + arr[i] = s.charAt(i) - '0'; } int num1 = 0; int num2 = 0; diff --git a/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java b/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java index 82f2d6709..3e6ebfe34 100644 --- a/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java +++ b/src/main/java/g3401_3500/s3464_maximize_the_distance_between_points_on_a_square/Solution.java @@ -15,7 +15,7 @@ public int maxDistance(int side, int[][] pts, int k) { if (y == 0) { c = x; } else if (x == side) { - c = side + y; + c = side + (long) y; } else if (y == side) { c = 2L * side + (side - x); } else {