From db81f6420e1235e62d41fd72bc3e295a754d1fc3 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 24 Nov 2024 06:04:21 +0200 Subject: [PATCH 01/16] Added tasks 3360-3363 --- .../s3360_stone_removal_game/Solution.java | 20 +++++++ .../s3360_stone_removal_game/readme.md | 37 ++++++++++++ .../Solution.java | 29 ++++++++++ .../readme.md | 47 ++++++++++++++++ .../Solution.java | 31 ++++++++++ .../readme.md | 55 ++++++++++++++++++ .../Solution.java | 41 ++++++++++++++ .../readme.md | 56 +++++++++++++++++++ .../SolutionTest.java | 18 ++++++ .../SolutionTest.java | 44 +++++++++++++++ .../SolutionTest.java | 33 +++++++++++ .../SolutionTest.java | 24 ++++++++ 12 files changed, 435 insertions(+) create mode 100644 src/main/java/g3301_3400/s3360_stone_removal_game/Solution.java create mode 100644 src/main/java/g3301_3400/s3360_stone_removal_game/readme.md create mode 100644 src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java create mode 100644 src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/readme.md create mode 100644 src/main/java/g3301_3400/s3362_zero_array_transformation_iii/Solution.java create mode 100644 src/main/java/g3301_3400/s3362_zero_array_transformation_iii/readme.md create mode 100644 src/main/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/Solution.java create mode 100644 src/main/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/readme.md create mode 100644 src/test/java/g3301_3400/s3360_stone_removal_game/SolutionTest.java create mode 100644 src/test/java/g3301_3400/s3361_shift_distance_between_two_strings/SolutionTest.java create mode 100644 src/test/java/g3301_3400/s3362_zero_array_transformation_iii/SolutionTest.java create mode 100644 src/test/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/SolutionTest.java diff --git a/src/main/java/g3301_3400/s3360_stone_removal_game/Solution.java b/src/main/java/g3301_3400/s3360_stone_removal_game/Solution.java new file mode 100644 index 000000000..d8bc45ded --- /dev/null +++ b/src/main/java/g3301_3400/s3360_stone_removal_game/Solution.java @@ -0,0 +1,20 @@ +package g3301_3400.s3360_stone_removal_game; + +// #Easy #2024_11_24_Time_0_ms_(100.00%)_Space_40.5_MB_(100.00%) + +public class Solution { + public boolean canAliceWin(int n) { + if (n < 10) { + return false; + } + int stonesRemaining = n - 10; + int stonesToBeRemoved = 9; + int i = 1; + while (stonesRemaining >= stonesToBeRemoved) { + stonesRemaining -= stonesToBeRemoved; + i++; + stonesToBeRemoved--; + } + return i % 2 != 0; + } +} diff --git a/src/main/java/g3301_3400/s3360_stone_removal_game/readme.md b/src/main/java/g3301_3400/s3360_stone_removal_game/readme.md new file mode 100644 index 000000000..aa45026ba --- /dev/null +++ b/src/main/java/g3301_3400/s3360_stone_removal_game/readme.md @@ -0,0 +1,37 @@ +3360\. Stone Removal Game + +Easy + +Alice and Bob are playing a game where they take turns removing stones from a pile, with _Alice going first_. + +* Alice starts by removing **exactly** 10 stones on her first turn. +* For each subsequent turn, each player removes **exactly** 1 fewer stone than the previous opponent. + +The player who cannot make a move loses the game. + +Given a positive integer `n`, return `true` if Alice wins the game and `false` otherwise. + +**Example 1:** + +**Input:** n = 12 + +**Output:** true + +**Explanation:** + +* Alice removes 10 stones on her first turn, leaving 2 stones for Bob. +* Bob cannot remove 9 stones, so Alice wins. + +**Example 2:** + +**Input:** n = 1 + +**Output:** false + +**Explanation:** + +* Alice cannot remove 10 stones, so Alice loses. + +**Constraints:** + +* `1 <= n <= 50` \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java b/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java new file mode 100644 index 000000000..55eb9ccdd --- /dev/null +++ b/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java @@ -0,0 +1,29 @@ +package g3301_3400.s3361_shift_distance_between_two_strings; + +// #Medium #2024_11_24_Time_57_ms_(100.00%)_Space_45.7_MB_(100.00%) + +public class Solution { + public long shiftDistance(String s, String t, int[] nextCost, int[] previousCost) { + long sum = 0; + int n = s.length(); + for (int i = 0; i < n; i++) { + int ch1 = s.charAt(i) - 'a'; + int ch2 = t.charAt(i) - 'a'; + if (ch1 == ch2) { + continue; + } + int forwardDiff = (ch2 - ch1 + 26) % 26; + long forwardCost = 0; + for (int j = 0; j < forwardDiff; j++) { + forwardCost += nextCost[(ch1 + j) % 26]; + } + int reverseDiff = (26 + ch1 - ch2) % 26; + long backwardCost = 0; + for (int j = 0; j < reverseDiff; j++) { + backwardCost += previousCost[(ch1 - j + 26) % 26]; + } + sum += Math.min(forwardCost, backwardCost); + } + return sum; + } +} diff --git a/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/readme.md b/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/readme.md new file mode 100644 index 000000000..6b219c884 --- /dev/null +++ b/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/readme.md @@ -0,0 +1,47 @@ +3361\. Shift Distance Between Two Strings + +Medium + +You are given two strings `s` and `t` of the same length, and two integer arrays `nextCost` and `previousCost`. + +In one operation, you can pick any index `i` of `s`, and perform **either one** of the following actions: + +* Shift `s[i]` to the next letter in the alphabet. If `s[i] == 'z'`, you should replace it with `'a'`. This operation costs `nextCost[j]` where `j` is the index of `s[i]` in the alphabet. +* Shift `s[i]` to the previous letter in the alphabet. If `s[i] == 'a'`, you should replace it with `'z'`. This operation costs `previousCost[j]` where `j` is the index of `s[i]` in the alphabet. + +The **shift distance** is the **minimum** total cost of operations required to transform `s` into `t`. + +Return the **shift distance** from `s` to `t`. + +**Example 1:** + +**Input:** s = "abab", t = "baba", nextCost = [100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], previousCost = [1,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + +**Output:** 2 + +**Explanation:** + +* We choose index `i = 0` and shift `s[0]` 25 times to the previous character for a total cost of 1. +* We choose index `i = 1` and shift `s[1]` 25 times to the next character for a total cost of 0. +* We choose index `i = 2` and shift `s[2]` 25 times to the previous character for a total cost of 1. +* We choose index `i = 3` and shift `s[3]` 25 times to the next character for a total cost of 0. + +**Example 2:** + +**Input:** s = "leet", t = "code", nextCost = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], previousCost = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] + +**Output:** 31 + +**Explanation:** + +* We choose index `i = 0` and shift `s[0]` 9 times to the previous character for a total cost of 9. +* We choose index `i = 1` and shift `s[1]` 10 times to the next character for a total cost of 10. +* We choose index `i = 2` and shift `s[2]` 1 time to the previous character for a total cost of 1. +* We choose index `i = 3` and shift `s[3]` 11 times to the next character for a total cost of 11. + +**Constraints:** + +* 1 <= s.length == t.length <= 105 +* `s` and `t` consist only of lowercase English letters. +* `nextCost.length == previousCost.length == 26` +* 0 <= nextCost[i], previousCost[i] <= 109 \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3362_zero_array_transformation_iii/Solution.java b/src/main/java/g3301_3400/s3362_zero_array_transformation_iii/Solution.java new file mode 100644 index 000000000..82de6fe21 --- /dev/null +++ b/src/main/java/g3301_3400/s3362_zero_array_transformation_iii/Solution.java @@ -0,0 +1,31 @@ +package g3301_3400.s3362_zero_array_transformation_iii; + +// #Medium #2024_11_24_Time_67_ms_(100.00%)_Space_89.9_MB_(66.67%) + +import java.util.Arrays; +import java.util.PriorityQueue; + +public class Solution { + public int maxRemoval(int[] nums, int[][] queries) { + Arrays.sort(queries, (a, b) -> a[0] - b[0]); + PriorityQueue last = new PriorityQueue<>((a, b) -> b - a); + int[] diffs = new int[nums.length + 1]; + int idx = 0; + int cur = 0; + for (int i = 0; i < nums.length; i++) { + while (idx < queries.length && queries[idx][0] == i) { + last.add(queries[idx][1]); + idx++; + } + cur += diffs[i]; + while (cur < nums[i] && !last.isEmpty() && last.peek() >= i) { + cur++; + diffs[last.poll() + 1]--; + } + if (cur < nums[i]) { + return -1; + } + } + return last.size(); + } +} diff --git a/src/main/java/g3301_3400/s3362_zero_array_transformation_iii/readme.md b/src/main/java/g3301_3400/s3362_zero_array_transformation_iii/readme.md new file mode 100644 index 000000000..c82de843a --- /dev/null +++ b/src/main/java/g3301_3400/s3362_zero_array_transformation_iii/readme.md @@ -0,0 +1,55 @@ +3362\. Zero Array Transformation III + +Medium + +You are given an integer array `nums` of length `n` and a 2D array `queries` where queries[i] = [li, ri]. + +Each `queries[i]` represents the following action on `nums`: + +* Decrement the value at each index in the range [li, ri] in `nums` by **at most** 1. +* The amount by which the value is decremented can be chosen **independently** for each index. + +A **Zero Array** is an array with all its elements equal to 0. + +Return the **maximum** number of elements that can be removed from `queries`, such that `nums` can still be converted to a **zero array** using the _remaining_ queries. If it is not possible to convert `nums` to a **zero array**, return -1. + +**Example 1:** + +**Input:** nums = [2,0,2], queries = [[0,2],[0,2],[1,1]] + +**Output:** 1 + +**Explanation:** + +After removing `queries[2]`, `nums` can still be converted to a zero array. + +* Using `queries[0]`, decrement `nums[0]` and `nums[2]` by 1 and `nums[1]` by 0. +* Using `queries[1]`, decrement `nums[0]` and `nums[2]` by 1 and `nums[1]` by 0. + +**Example 2:** + +**Input:** nums = [1,1,1,1], queries = [[1,3],[0,2],[1,3],[1,2]] + +**Output:** 2 + +**Explanation:** + +We can remove `queries[2]` and `queries[3]`. + +**Example 3:** + +**Input:** nums = [1,2,3,4], queries = [[0,3]] + +**Output:** \-1 + +**Explanation:** + +`nums` cannot be converted to a zero array even after using all the queries. + +**Constraints:** + +* 1 <= nums.length <= 105 +* 0 <= nums[i] <= 105 +* 1 <= queries.length <= 105 +* `queries[i].length == 2` +* 0 <= li <= ri < nums.length \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/Solution.java b/src/main/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/Solution.java new file mode 100644 index 000000000..bf4e60b0f --- /dev/null +++ b/src/main/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/Solution.java @@ -0,0 +1,41 @@ +package g3301_3400.s3363_find_the_maximum_number_of_fruits_collected; + +// #Hard #2024_11_24_Time_13_ms_(100.00%)_Space_142.3_MB_(33.33%) + +public class Solution { + public int maxCollectedFruits(int[][] fruits) { + int n = fruits.length; + // Set inaccessible cells to 0 + for (int i = 0; i < n; ++i) { + for (int j = 0; j < n; ++j) { + if (i < j && j < n - 1 - i) { + fruits[i][j] = 0; + } + if (j < i && i < n - 1 - j) { + fruits[i][j] = 0; + } + } + } + int res = 0; + for (int i = 0; i < n; ++i) { + res += fruits[i][i]; + } + for (int i = 1; i < n; ++i) { + for (int j = i + 1; j < n; ++j) { + fruits[i][j] += + Math.max( + fruits[i - 1][j - 1], + Math.max(fruits[i - 1][j], (j + 1 < n) ? fruits[i - 1][j + 1] : 0)); + } + } + for (int j = 1; j < n; ++j) { + for (int i = j + 1; i < n; ++i) { + fruits[i][j] += + Math.max( + fruits[i - 1][j - 1], + Math.max(fruits[i][j - 1], (i + 1 < n) ? fruits[i + 1][j - 1] : 0)); + } + } + return res + fruits[n - 1][n - 2] + fruits[n - 2][n - 1]; + } +} diff --git a/src/main/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/readme.md b/src/main/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/readme.md new file mode 100644 index 000000000..82f4c3200 --- /dev/null +++ b/src/main/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/readme.md @@ -0,0 +1,56 @@ +3363\. Find the Maximum Number of Fruits Collected + +Hard + +There is a game dungeon comprised of `n x n` rooms arranged in a grid. + +You are given a 2D array `fruits` of size `n x n`, where `fruits[i][j]` represents the number of fruits in the room `(i, j)`. Three children will play in the game dungeon, with **initial** positions at the corner rooms `(0, 0)`, `(0, n - 1)`, and `(n - 1, 0)`. + +The children will make **exactly** `n - 1` moves according to the following rules to reach the room `(n - 1, n - 1)`: + +* The child starting from `(0, 0)` must move from their current room `(i, j)` to one of the rooms `(i + 1, j + 1)`, `(i + 1, j)`, and `(i, j + 1)` if the target room exists. +* The child starting from `(0, n - 1)` must move from their current room `(i, j)` to one of the rooms `(i + 1, j - 1)`, `(i + 1, j)`, and `(i + 1, j + 1)` if the target room exists. +* The child starting from `(n - 1, 0)` must move from their current room `(i, j)` to one of the rooms `(i - 1, j + 1)`, `(i, j + 1)`, and `(i + 1, j + 1)` if the target room exists. + +When a child enters a room, they will collect all the fruits there. If two or more children enter the same room, only one child will collect the fruits, and the room will be emptied after they leave. + +Return the **maximum** number of fruits the children can collect from the dungeon. + +**Example 1:** + +**Input:** fruits = [[1,2,3,4],[5,6,8,7],[9,10,11,12],[13,14,15,16]] + +**Output:** 100 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2024/10/15/example_1.gif) + +In this example: + +* The 1st child (green) moves on the path `(0,0) -> (1,1) -> (2,2) -> (3, 3)`. +* The 2nd child (red) moves on the path `(0,3) -> (1,2) -> (2,3) -> (3, 3)`. +* The 3rd child (blue) moves on the path `(3,0) -> (3,1) -> (3,2) -> (3, 3)`. + +In total they collect `1 + 6 + 11 + 1 + 4 + 8 + 12 + 13 + 14 + 15 = 100` fruits. + +**Example 2:** + +**Input:** fruits = [[1,1],[1,1]] + +**Output:** 4 + +**Explanation:** + +In this example: + +* The 1st child moves on the path `(0,0) -> (1,1)`. +* The 2nd child moves on the path `(0,1) -> (1,1)`. +* The 3rd child moves on the path `(1,0) -> (1,1)`. + +In total they collect `1 + 1 + 1 + 1 = 4` fruits. + +**Constraints:** + +* `2 <= n == fruits.length == fruits[i].length <= 1000` +* `0 <= fruits[i][j] <= 1000` \ No newline at end of file diff --git a/src/test/java/g3301_3400/s3360_stone_removal_game/SolutionTest.java b/src/test/java/g3301_3400/s3360_stone_removal_game/SolutionTest.java new file mode 100644 index 000000000..268583410 --- /dev/null +++ b/src/test/java/g3301_3400/s3360_stone_removal_game/SolutionTest.java @@ -0,0 +1,18 @@ +package g3301_3400.s3360_stone_removal_game; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void canAliceWin() { + assertThat(new Solution().canAliceWin(12), equalTo(true)); + } + + @Test + void canAliceWin2() { + assertThat(new Solution().canAliceWin(1), equalTo(false)); + } +} diff --git a/src/test/java/g3301_3400/s3361_shift_distance_between_two_strings/SolutionTest.java b/src/test/java/g3301_3400/s3361_shift_distance_between_two_strings/SolutionTest.java new file mode 100644 index 000000000..39c2191e0 --- /dev/null +++ b/src/test/java/g3301_3400/s3361_shift_distance_between_two_strings/SolutionTest.java @@ -0,0 +1,44 @@ +package g3301_3400.s3361_shift_distance_between_two_strings; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void shiftDistance() { + assertThat( + new Solution() + .shiftDistance( + "abab", + "baba", + new int[] { + 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 + }, + new int[] { + 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 + }), + equalTo(2L)); + } + + @Test + void shiftDistance2() { + assertThat( + new Solution() + .shiftDistance( + "leet", + "code", + new int[] { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + }, + new int[] { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + }), + equalTo(31L)); + } +} diff --git a/src/test/java/g3301_3400/s3362_zero_array_transformation_iii/SolutionTest.java b/src/test/java/g3301_3400/s3362_zero_array_transformation_iii/SolutionTest.java new file mode 100644 index 000000000..1d5b4591e --- /dev/null +++ b/src/test/java/g3301_3400/s3362_zero_array_transformation_iii/SolutionTest.java @@ -0,0 +1,33 @@ +package g3301_3400.s3362_zero_array_transformation_iii; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxRemoval() { + assertThat( + new Solution() + .maxRemoval(new int[] {2, 0, 2}, new int[][] {{0, 2}, {0, 2}, {1, 1}}), + equalTo(1)); + } + + @Test + void maxRemoval2() { + assertThat( + new Solution() + .maxRemoval( + new int[] {1, 1, 1, 1}, + new int[][] {{1, 3}, {0, 2}, {1, 3}, {1, 2}}), + equalTo(2)); + } + + @Test + void maxRemoval3() { + assertThat( + new Solution().maxRemoval(new int[] {1, 2, 3, 4}, new int[][] {{0, 3}}), + equalTo(-1)); + } +} diff --git a/src/test/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/SolutionTest.java b/src/test/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/SolutionTest.java new file mode 100644 index 000000000..ad24df6fc --- /dev/null +++ b/src/test/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/SolutionTest.java @@ -0,0 +1,24 @@ +package g3301_3400.s3363_find_the_maximum_number_of_fruits_collected; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxCollectedFruits() { + assertThat( + new Solution() + .maxCollectedFruits( + new int[][] { + {1, 2, 3, 4}, {5, 6, 8, 7}, {9, 10, 11, 12}, {13, 14, 15, 16} + }), + equalTo(100)); + } + + @Test + void maxCollectedFruits2() { + assertThat(new Solution().maxCollectedFruits(new int[][] {{1, 1}, {1, 1}}), equalTo(4)); + } +} From 12b5e8ee4ed4784337c3a379cdc513dbde51c530 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 24 Nov 2024 06:12:15 +0200 Subject: [PATCH 02/16] Added test --- .../s3361_shift_distance_between_two_strings/Solution.java | 3 --- .../g3301_3400/s3360_stone_removal_game/SolutionTest.java | 5 +++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java b/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java index 55eb9ccdd..c25bc4cee 100644 --- a/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java +++ b/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java @@ -9,9 +9,6 @@ public long shiftDistance(String s, String t, int[] nextCost, int[] previousCost for (int i = 0; i < n; i++) { int ch1 = s.charAt(i) - 'a'; int ch2 = t.charAt(i) - 'a'; - if (ch1 == ch2) { - continue; - } int forwardDiff = (ch2 - ch1 + 26) % 26; long forwardCost = 0; for (int j = 0; j < forwardDiff; j++) { diff --git a/src/test/java/g3301_3400/s3360_stone_removal_game/SolutionTest.java b/src/test/java/g3301_3400/s3360_stone_removal_game/SolutionTest.java index 268583410..084229aab 100644 --- a/src/test/java/g3301_3400/s3360_stone_removal_game/SolutionTest.java +++ b/src/test/java/g3301_3400/s3360_stone_removal_game/SolutionTest.java @@ -15,4 +15,9 @@ void canAliceWin() { void canAliceWin2() { assertThat(new Solution().canAliceWin(1), equalTo(false)); } + + @Test + void canAliceWin3() { + assertThat(new Solution().canAliceWin(19), equalTo(false)); + } } From b85ca079b3671c7a635d7b41af3f55aff0f74220 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 24 Nov 2024 16:08:37 +0200 Subject: [PATCH 03/16] Added tasks 3364-3367 --- .../Solution.java | 26 +++++++++ .../readme.md | 52 ++++++++++++++++++ .../Solution.java | 27 ++++++++++ .../readme.md | 54 +++++++++++++++++++ .../s3366_minimum_array_sum/Solution.java | 37 +++++++++++++ .../s3366_minimum_array_sum/readme.md | 46 ++++++++++++++++ .../Solution.java | 35 ++++++++++++ .../readme.md | 47 ++++++++++++++++ .../SolutionTest.java | 24 +++++++++ .../SolutionTest.java | 23 ++++++++ .../s3366_minimum_array_sum/SolutionTest.java | 18 +++++++ .../SolutionTest.java | 34 ++++++++++++ 12 files changed, 423 insertions(+) create mode 100644 src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/Solution.java create mode 100644 src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/readme.md create mode 100644 src/main/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/Solution.java create mode 100644 src/main/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/readme.md create mode 100644 src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java create mode 100644 src/main/java/g3301_3400/s3366_minimum_array_sum/readme.md create mode 100644 src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java create mode 100644 src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/readme.md create mode 100644 src/test/java/g3301_3400/s3364_minimum_positive_sum_subarray/SolutionTest.java create mode 100644 src/test/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/SolutionTest.java create mode 100644 src/test/java/g3301_3400/s3366_minimum_array_sum/SolutionTest.java create mode 100644 src/test/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/SolutionTest.java diff --git a/src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/Solution.java b/src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/Solution.java new file mode 100644 index 000000000..9a13f1ef1 --- /dev/null +++ b/src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/Solution.java @@ -0,0 +1,26 @@ +package g3301_3400.s3364_minimum_positive_sum_subarray; + +// #Easy #2024_11_24_Time_28_ms_(100.00%)_Space_44.7_MB_(100.00%) + +import java.util.List; + +public class Solution { + public int minimumSumSubarray(List nums, int l, int r) { + int size = nums.size(); + int res = -1; + for (int s = l; s <= r; s++) { + for (int i = 0; i <= size - s; i++) { + int sum = 0; + for (int j = i; j < i + s; j++) { + sum += nums.get(j); + } + if (sum > 0) { + if (res == -1 || res > sum) { + res = sum; + } + } + } + } + return res; + } +} diff --git a/src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/readme.md b/src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/readme.md new file mode 100644 index 000000000..97fae38a4 --- /dev/null +++ b/src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/readme.md @@ -0,0 +1,52 @@ +3364\. Minimum Positive Sum Subarray + +Easy + +You are given an integer array `nums` and **two** integers `l` and `r`. Your task is to find the **minimum** sum of a **subarray** whose size is between `l` and `r` (inclusive) and whose sum is greater than 0. + +Return the **minimum** sum of such a subarray. If no such subarray exists, return -1. + +A **subarray** is a contiguous **non-empty** sequence of elements within an array. + +**Example 1:** + +**Input:** nums = [3, -2, 1, 4], l = 2, r = 3 + +**Output:** 1 + +**Explanation:** + +The subarrays of length between `l = 2` and `r = 3` where the sum is greater than 0 are: + +* `[3, -2]` with a sum of 1 +* `[1, 4]` with a sum of 5 +* `[3, -2, 1]` with a sum of 2 +* `[-2, 1, 4]` with a sum of 3 + +Out of these, the subarray `[3, -2]` has a sum of 1, which is the smallest positive sum. Hence, the answer is 1. + +**Example 2:** + +**Input:** nums = [-2, 2, -3, 1], l = 2, r = 3 + +**Output:** \-1 + +**Explanation:** + +There is no subarray of length between `l` and `r` that has a sum greater than 0. So, the answer is -1. + +**Example 3:** + +**Input:** nums = [1, 2, 3, 4], l = 2, r = 4 + +**Output:** 3 + +**Explanation:** + +The subarray `[1, 2]` has a length of 2 and the minimum sum greater than 0. So, the answer is 3. + +**Constraints:** + +* `1 <= nums.length <= 100` +* `1 <= l <= r <= nums.length` +* `-1000 <= nums[i] <= 1000` \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/Solution.java b/src/main/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/Solution.java new file mode 100644 index 000000000..5c14fabae --- /dev/null +++ b/src/main/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/Solution.java @@ -0,0 +1,27 @@ +package g3301_3400.s3365_rearrange_k_substrings_to_form_target_string; + +// #Medium #2024_11_24_Time_61_ms_(100.00%)_Space_49.3_MB_(100.00%) + +import java.util.HashMap; +import java.util.Map; + +public class Solution { + public boolean isPossibleToRearrange(String s, String t, int k) { + int size = s.length(); + int div = size / k; + Map map = new HashMap<>(); + for (int i = 0; i < size; i += div) { + String sub = s.substring(i, i + div); + map.put(sub, map.getOrDefault(sub, 0) + 1); + } + for (int i = 0; i < size; i += div) { + String sub = t.substring(i, i + div); + if (map.getOrDefault(sub, 0) > 0) { + map.put(sub, map.get(sub) - 1); + } else { + return false; + } + } + return true; + } +} diff --git a/src/main/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/readme.md b/src/main/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/readme.md new file mode 100644 index 000000000..d9eb1a2db --- /dev/null +++ b/src/main/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/readme.md @@ -0,0 +1,54 @@ +3365\. Rearrange K Substrings to Form Target String + +Medium + +You are given two strings `s` and `t`, both of which are anagrams of each other, and an integer `k`. + +Your task is to determine whether it is possible to split the string `s` into `k` equal-sized substrings, rearrange the substrings, and concatenate them in _any order_ to create a new string that matches the given string `t`. + +Return `true` if this is possible, otherwise, return `false`. + +An **anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, using all the original letters exactly once. + +A **substring** is a contiguous **non-empty** sequence of characters within a string. + +**Example 1:** + +**Input:** s = "abcd", t = "cdab", k = 2 + +**Output:** true + +**Explanation:** + +* Split `s` into 2 substrings of length 2: `["ab", "cd"]`. +* Rearranging these substrings as `["cd", "ab"]`, and then concatenating them results in `"cdab"`, which matches `t`. + +**Example 2:** + +**Input:** s = "aabbcc", t = "bbaacc", k = 3 + +**Output:** true + +**Explanation:** + +* Split `s` into 3 substrings of length 2: `["aa", "bb", "cc"]`. +* Rearranging these substrings as `["bb", "aa", "cc"]`, and then concatenating them results in `"bbaacc"`, which matches `t`. + +**Example 3:** + +**Input:** s = "aabbcc", t = "bbaacc", k = 2 + +**Output:** false + +**Explanation:** + +* Split `s` into 2 substrings of length 3: `["aab", "bcc"]`. +* These substrings cannot be rearranged to form `t = "bbaacc"`, so the output is `false`. + +**Constraints:** + +* 1 <= s.length == t.length <= 2 * 105 +* `1 <= k <= s.length` +* `s.length` is divisible by `k`. +* `s` and `t` consist only of lowercase English letters. +* The input is generated such that `s` and `t` are anagrams of each other. \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java b/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java new file mode 100644 index 000000000..137aa02e6 --- /dev/null +++ b/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java @@ -0,0 +1,37 @@ +package g3301_3400.s3366_minimum_array_sum; + +// #Medium #2024_11_24_Time_66_ms_(100.00%)_Space_55_MB_(100.00%) + +public class Solution { + public int minArraySum(int[] nums, int k, int op1, int op2) { + Integer[][][] dp = new Integer[nums.length][op1 + 1][op2 + 1]; + return sub(dp, nums, 0, k, op1, op2); + } + + private int sub(Integer[][][] dp, int[] nums, int i, int k, int op1, int op2) { + if (i == nums.length) { + return 0; + } + if (dp[i][op1][op2] != null) { + return dp[i][op1][op2]; + } + int res = sub(dp, nums, i + 1, k, op1, op2) + nums[i]; + if (nums[i] >= k && op2 > 0) { + res = Math.min(res, sub(dp, nums, i + 1, k, op1, op2 - 1) + nums[i] - k); + int v = (int) Math.ceil(nums[i] / 2.0); + if (v < k) { + v = (int) Math.ceil((nums[i] - k) / 2.0); + } else { + v -= k; + } + if (op1 > 0) { + res = Math.min(res, sub(dp, nums, i + 1, k, op1 - 1, op2 - 1) + v); + } + } + if (op1 > 0) { + int v = (int) Math.ceil(nums[i] / 2.0); + res = Math.min(res, sub(dp, nums, i + 1, k, op1 - 1, op2) + v); + } + return dp[i][op1][op2] = res; + } +} diff --git a/src/main/java/g3301_3400/s3366_minimum_array_sum/readme.md b/src/main/java/g3301_3400/s3366_minimum_array_sum/readme.md new file mode 100644 index 000000000..086dfd9db --- /dev/null +++ b/src/main/java/g3301_3400/s3366_minimum_array_sum/readme.md @@ -0,0 +1,46 @@ +3366\. Minimum Array Sum + +Medium + +You are given an integer array `nums` and three integers `k`, `op1`, and `op2`. + +You can perform the following operations on `nums`: + +* **Operation 1**: Choose an index `i` and divide `nums[i]` by 2, **rounding up** to the nearest whole number. You can perform this operation at most `op1` times, and not more than **once** per index. +* **Operation 2**: Choose an index `i` and subtract `k` from `nums[i]`, but only if `nums[i]` is greater than or equal to `k`. You can perform this operation at most `op2` times, and not more than **once** per index. + +**Note:** Both operations can be applied to the same index, but at most once each. + +Return the **minimum** possible **sum** of all elements in `nums` after performing any number of operations. + +**Example 1:** + +**Input:** nums = [2,8,3,19,3], k = 3, op1 = 1, op2 = 1 + +**Output:** 23 + +**Explanation:** + +* Apply Operation 2 to `nums[1] = 8`, making `nums[1] = 5`. +* Apply Operation 1 to `nums[3] = 19`, making `nums[3] = 10`. +* The resulting array becomes `[2, 5, 3, 10, 3]`, which has the minimum possible sum of 23 after applying the operations. + +**Example 2:** + +**Input:** nums = [2,4,3], k = 3, op1 = 2, op2 = 1 + +**Output:** 3 + +**Explanation:** + +* Apply Operation 1 to `nums[0] = 2`, making `nums[0] = 1`. +* Apply Operation 1 to `nums[1] = 4`, making `nums[1] = 2`. +* Apply Operation 2 to `nums[2] = 3`, making `nums[2] = 0`. +* The resulting array becomes `[1, 2, 0]`, which has the minimum possible sum of 3 after applying the operations. + +**Constraints:** + +* `1 <= nums.length <= 100` +* 0 <= nums[i] <= 105 +* 0 <= k <= 105 +* `0 <= op1, op2 <= nums.length` \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java b/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java new file mode 100644 index 000000000..d73ad344f --- /dev/null +++ b/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java @@ -0,0 +1,35 @@ +package g3301_3400.s3367_maximize_sum_of_weights_after_edge_removals; + +// #Hard #2024_11_24_Time_147_ms_(100.00%)_Space_142.2_MB_(100.00%) + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.PriorityQueue; + +public class Solution { + public long maximizeSumOfWeights(int[][] edges, int k) { + HashMap> map = new HashMap<>(); + for (int[] edge : edges) { + map.computeIfAbsent(edge[0], t -> new ArrayList<>()).add(new int[] {edge[1], edge[2]}); + map.computeIfAbsent(edge[1], t -> new ArrayList<>()).add(new int[] {edge[0], edge[2]}); + } + return maximizeSumOfWeights(0, -1, k, map)[0]; + } + + private long[] maximizeSumOfWeights( + int v, int from, int k, HashMap> map) { + long sum = 0; + PriorityQueue queue = new PriorityQueue<>(); + for (int[] i : map.get(v)) { + if (i[0] != from) { + long[] next = maximizeSumOfWeights(i[0], v, k, map); + sum += Math.max(next[0], next[1] += i[1]); + if (next[0] < next[1]) { + queue.offer(next[1] - next[0]); + sum -= queue.size() > k ? queue.poll() : 0; + } + } + } + return new long[] {sum, sum - (queue.size() < k ? 0 : queue.peek())}; + } +} diff --git a/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/readme.md b/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/readme.md new file mode 100644 index 000000000..e28eec246 --- /dev/null +++ b/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/readme.md @@ -0,0 +1,47 @@ +3367\. Maximize Sum of Weights after Edge Removals + +Hard + +There exists an **undirected** tree with `n` nodes numbered `0` to `n - 1`. You are given a 2D integer array `edges` of length `n - 1`, where edges[i] = [ui, vi, wi] indicates that there is an edge between nodes ui and vi with weight wi in the tree. + +Your task is to remove _zero or more_ edges such that: + +* Each node has an edge with **at most** `k` other nodes, where `k` is given. +* The sum of the weights of the remaining edges is **maximized**. + +Return the **maximum** possible sum of weights for the remaining edges after making the necessary removals. + +**Example 1:** + +**Input:** edges = [[0,1,4],[0,2,2],[2,3,12],[2,4,6]], k = 2 + +**Output:** 22 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2024/10/30/test1drawio.png) + +* Node 2 has edges with 3 other nodes. We remove the edge `[0, 2, 2]`, ensuring that no node has edges with more than `k = 2` nodes. +* The sum of weights is 22, and we can't achieve a greater sum. Thus, the answer is 22. + +**Example 2:** + +**Input:** edges = [[0,1,5],[1,2,10],[0,3,15],[3,4,20],[3,5,5],[0,6,10]], k = 3 + +**Output:** 65 + +**Explanation:** + +* Since no node has edges connecting it to more than `k = 3` nodes, we don't remove any edges. +* The sum of weights is 65. Thus, the answer is 65. + +**Constraints:** + +* 2 <= n <= 105 +* `1 <= k <= n - 1` +* `edges.length == n - 1` +* `edges[i].length == 3` +* `0 <= edges[i][0] <= n - 1` +* `0 <= edges[i][1] <= n - 1` +* 1 <= edges[i][2] <= 106 +* The input is generated such that `edges` form a valid tree. \ No newline at end of file diff --git a/src/test/java/g3301_3400/s3364_minimum_positive_sum_subarray/SolutionTest.java b/src/test/java/g3301_3400/s3364_minimum_positive_sum_subarray/SolutionTest.java new file mode 100644 index 000000000..6778792c1 --- /dev/null +++ b/src/test/java/g3301_3400/s3364_minimum_positive_sum_subarray/SolutionTest.java @@ -0,0 +1,24 @@ +package g3301_3400.s3364_minimum_positive_sum_subarray; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void minimumSumSubarray() { + assertThat(new Solution().minimumSumSubarray(List.of(3, -2, 1, 4), 2, 3), equalTo(1)); + } + + @Test + void minimumSumSubarray2() { + assertThat(new Solution().minimumSumSubarray(List.of(-2, 2, -3, 1), 2, 3), equalTo(-1)); + } + + @Test + void minimumSumSubarray3() { + assertThat(new Solution().minimumSumSubarray(List.of(1, 2, 3, 4), 2, 4), equalTo(3)); + } +} diff --git a/src/test/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/SolutionTest.java b/src/test/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/SolutionTest.java new file mode 100644 index 000000000..5d14f5870 --- /dev/null +++ b/src/test/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/SolutionTest.java @@ -0,0 +1,23 @@ +package g3301_3400.s3365_rearrange_k_substrings_to_form_target_string; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void isPossibleToRearrange() { + assertThat(new Solution().isPossibleToRearrange("abcd", "cdab", 2), equalTo(true)); + } + + @Test + void isPossibleToRearrange2() { + assertThat(new Solution().isPossibleToRearrange("aabbcc", "bbaacc", 3), equalTo(true)); + } + + @Test + void isPossibleToRearrange3() { + assertThat(new Solution().isPossibleToRearrange("aabbcc", "bbaacc", 2), equalTo(false)); + } +} diff --git a/src/test/java/g3301_3400/s3366_minimum_array_sum/SolutionTest.java b/src/test/java/g3301_3400/s3366_minimum_array_sum/SolutionTest.java new file mode 100644 index 000000000..aed497bf9 --- /dev/null +++ b/src/test/java/g3301_3400/s3366_minimum_array_sum/SolutionTest.java @@ -0,0 +1,18 @@ +package g3301_3400.s3366_minimum_array_sum; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void minArraySum() { + assertThat(new Solution().minArraySum(new int[] {2, 8, 3, 19, 3}, 3, 1, 1), equalTo(23)); + } + + @Test + void minArraySum2() { + assertThat(new Solution().minArraySum(new int[] {2, 4, 3}, 3, 2, 1), equalTo(3)); + } +} diff --git a/src/test/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/SolutionTest.java b/src/test/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/SolutionTest.java new file mode 100644 index 000000000..412a05941 --- /dev/null +++ b/src/test/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/SolutionTest.java @@ -0,0 +1,34 @@ +package g3301_3400.s3367_maximize_sum_of_weights_after_edge_removals; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maximizeSumOfWeights() { + assertThat( + new Solution() + .maximizeSumOfWeights( + new int[][] {{0, 1, 4}, {0, 2, 2}, {2, 3, 12}, {2, 4, 6}}, 2), + equalTo(22L)); + } + + @Test + void maximizeSumOfWeights2() { + assertThat( + new Solution() + .maximizeSumOfWeights( + new int[][] { + {0, 1, 5}, + {1, 2, 10}, + {0, 3, 15}, + {3, 4, 20}, + {3, 5, 5}, + {0, 6, 10} + }, + 3), + equalTo(65L)); + } +} From 3c0e0a725de597574ee0e4247334bbba76d38b4c Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 24 Nov 2024 16:22:31 +0200 Subject: [PATCH 04/16] Fixed sonar --- .../s3364_minimum_positive_sum_subarray/Solution.java | 6 ++---- .../java/g3301_3400/s3366_minimum_array_sum/Solution.java | 3 ++- .../Solution.java | 3 ++- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/Solution.java b/src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/Solution.java index 9a13f1ef1..3d027702f 100644 --- a/src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/Solution.java +++ b/src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/Solution.java @@ -14,10 +14,8 @@ public int minimumSumSubarray(List nums, int l, int r) { for (int j = i; j < i + s; j++) { sum += nums.get(j); } - if (sum > 0) { - if (res == -1 || res > sum) { - res = sum; - } + if (sum > 0 && (res == -1 || res > sum)) { + res = sum; } } } diff --git a/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java b/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java index 137aa02e6..b4e5ecf7b 100644 --- a/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java +++ b/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java @@ -32,6 +32,7 @@ private int sub(Integer[][][] dp, int[] nums, int i, int k, int op1, int op2) { int v = (int) Math.ceil(nums[i] / 2.0); res = Math.min(res, sub(dp, nums, i + 1, k, op1 - 1, op2) + v); } - return dp[i][op1][op2] = res; + dp[i][op1][op2] = res; + return res; } } diff --git a/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java b/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java index d73ad344f..ee7765b2c 100644 --- a/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java +++ b/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java @@ -23,7 +23,8 @@ private long[] maximizeSumOfWeights( for (int[] i : map.get(v)) { if (i[0] != from) { long[] next = maximizeSumOfWeights(i[0], v, k, map); - sum += Math.max(next[0], next[1] += i[1]); + next[1] += i[1]; + sum += Math.max(next[0], next[1]); if (next[0] < next[1]) { queue.offer(next[1] - next[0]); sum -= queue.size() > k ? queue.poll() : 0; From 4968d4acca0993e4e85501211d8d3b4c1b034672 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Wed, 27 Nov 2024 11:20:57 +0200 Subject: [PATCH 05/16] Improved task 3367 --- .../Solution.java | 55 ++++++++++++------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java b/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java index ee7765b2c..941cc781e 100644 --- a/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java +++ b/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java @@ -1,36 +1,51 @@ package g3301_3400.s3367_maximize_sum_of_weights_after_edge_removals; -// #Hard #2024_11_24_Time_147_ms_(100.00%)_Space_142.2_MB_(100.00%) +// #Hard #2024_11_27_Time_87_ms_(98.35%)_Space_152.7_MB_(18.13%) import java.util.ArrayList; -import java.util.HashMap; +import java.util.List; import java.util.PriorityQueue; public class Solution { + private List[] adj; + private int k; + public long maximizeSumOfWeights(int[][] edges, int k) { - HashMap> map = new HashMap<>(); - for (int[] edge : edges) { - map.computeIfAbsent(edge[0], t -> new ArrayList<>()).add(new int[] {edge[1], edge[2]}); - map.computeIfAbsent(edge[1], t -> new ArrayList<>()).add(new int[] {edge[0], edge[2]}); + int n = edges.length + 1; + adj = new List[n]; + this.k = k; + for (int i = 0; i < n; i++) { + adj[i] = new ArrayList<>(); + } + for (int[] e : edges) { + adj[e[0]].add(e); + adj[e[1]].add(e); } - return maximizeSumOfWeights(0, -1, k, map)[0]; + return dfs(0, -1)[1]; } - private long[] maximizeSumOfWeights( - int v, int from, int k, HashMap> map) { + private long[] dfs(int v, int parent) { long sum = 0; - PriorityQueue queue = new PriorityQueue<>(); - for (int[] i : map.get(v)) { - if (i[0] != from) { - long[] next = maximizeSumOfWeights(i[0], v, k, map); - next[1] += i[1]; - sum += Math.max(next[0], next[1]); - if (next[0] < next[1]) { - queue.offer(next[1] - next[0]); - sum -= queue.size() > k ? queue.poll() : 0; - } + PriorityQueue pq = new PriorityQueue<>(); + for (int[] e : adj[v]) { + int w = e[0] == v ? e[1] : e[0]; + if (w == parent) { + continue; } + long[] res = dfs(w, v); + long max = Math.max(e[2] + res[0], res[1]); + sum += max; + pq.add(max - res[1]); + } + long[] res = new long[2]; + while (pq.size() > k) { + sum -= pq.poll(); + } + res[1] = sum; + while (pq.size() > k - 1) { + sum -= pq.poll(); } - return new long[] {sum, sum - (queue.size() < k ? 0 : queue.peek())}; + res[0] = sum; + return res; } } From 7f09298d5626f93775d2b154c96d5998556de2ab Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Wed, 27 Nov 2024 11:23:35 +0200 Subject: [PATCH 06/16] Fixed compile warning --- .../Solution.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java b/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java index 941cc781e..766d66e17 100644 --- a/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java +++ b/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.PriorityQueue; +@SuppressWarnings("unchecked") public class Solution { private List[] adj; private int k; From 4fd65cbe3cb20392f212f0b1250885f092a399cf Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 1 Dec 2024 13:41:57 +0200 Subject: [PATCH 07/16] Added tasks 3370-3373 --- .../Solution.java | 13 +++ .../readme.md | 43 ++++++++++ .../Solution.java | 33 +++++++ .../readme.md | 47 ++++++++++ .../Solution.java | 68 +++++++++++++++ .../readme.md | 54 ++++++++++++ .../Solution.java | 85 +++++++++++++++++++ .../readme.md | 53 ++++++++++++ .../SolutionTest.java | 23 +++++ .../SolutionTest.java | 23 +++++ .../SolutionTest.java | 32 +++++++ .../SolutionTest.java | 30 +++++++ 12 files changed, 504 insertions(+) create mode 100644 src/main/java/g3301_3400/s3370_smallest_number_with_all_set_bits/Solution.java create mode 100644 src/main/java/g3301_3400/s3370_smallest_number_with_all_set_bits/readme.md create mode 100644 src/main/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/Solution.java create mode 100644 src/main/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/readme.md create mode 100644 src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/Solution.java create mode 100644 src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/readme.md create mode 100644 src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java create mode 100644 src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/readme.md create mode 100644 src/test/java/g3301_3400/s3370_smallest_number_with_all_set_bits/SolutionTest.java create mode 100644 src/test/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/SolutionTest.java create mode 100644 src/test/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/SolutionTest.java create mode 100644 src/test/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/SolutionTest.java diff --git a/src/main/java/g3301_3400/s3370_smallest_number_with_all_set_bits/Solution.java b/src/main/java/g3301_3400/s3370_smallest_number_with_all_set_bits/Solution.java new file mode 100644 index 000000000..b4668d1c6 --- /dev/null +++ b/src/main/java/g3301_3400/s3370_smallest_number_with_all_set_bits/Solution.java @@ -0,0 +1,13 @@ +package g3301_3400.s3370_smallest_number_with_all_set_bits; + +// #Easy #2024_12_01_Time_0_ms_(100.00%)_Space_40.7_MB_(100.00%) + +public class Solution { + public int smallestNumber(int n) { + int res = 1; + while (res < n) { + res = res * 2 + 1; + } + return res; + } +} diff --git a/src/main/java/g3301_3400/s3370_smallest_number_with_all_set_bits/readme.md b/src/main/java/g3301_3400/s3370_smallest_number_with_all_set_bits/readme.md new file mode 100644 index 000000000..ce5862a88 --- /dev/null +++ b/src/main/java/g3301_3400/s3370_smallest_number_with_all_set_bits/readme.md @@ -0,0 +1,43 @@ +3370\. Smallest Number With All Set Bits + +Easy + +You are given a _positive_ number `n`. + +Return the **smallest** number `x` **greater than** or **equal to** `n`, such that the binary representation of `x` contains only **set** bits. + +A **set** bit refers to a bit in the binary representation of a number that has a value of `1`. + +**Example 1:** + +**Input:** n = 5 + +**Output:** 7 + +**Explanation:** + +The binary representation of 7 is `"111"`. + +**Example 2:** + +**Input:** n = 10 + +**Output:** 15 + +**Explanation:** + +The binary representation of 15 is `"1111"`. + +**Example 3:** + +**Input:** n = 3 + +**Output:** 3 + +**Explanation:** + +The binary representation of 3 is `"11"`. + +**Constraints:** + +* `1 <= n <= 1000` \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/Solution.java b/src/main/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/Solution.java new file mode 100644 index 000000000..430801b34 --- /dev/null +++ b/src/main/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/Solution.java @@ -0,0 +1,33 @@ +package g3301_3400.s3371_identify_the_largest_outlier_in_an_array; + +// #Medium #2024_12_01_Time_633_ms_(100.00%)_Space_64.5_MB_(100.00%) + +import java.util.TreeMap; + +public class Solution { + public int getLargestOutlier(int[] nums) { + int sum = 0; + for (int num : nums) { + sum += num; + } + TreeMap frequencyMap = new TreeMap<>(); + for (int num : nums) { + frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1); + } + int ans = Integer.MIN_VALUE; + for (int num : nums) { + if ((sum - num) % 2 == 0) { + int target = (sum - num) / 2; + frequencyMap.put(num, frequencyMap.get(num) - 1); + if (frequencyMap.get(num) == 0) { + frequencyMap.remove(num); + } + if (frequencyMap.containsKey(target)) { + ans = Math.max(ans, num); + } + frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1); + } + } + return ans == Integer.MIN_VALUE ? -1 : ans; + } +} diff --git a/src/main/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/readme.md b/src/main/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/readme.md new file mode 100644 index 000000000..091cd961f --- /dev/null +++ b/src/main/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/readme.md @@ -0,0 +1,47 @@ +3371\. Identify the Largest Outlier in an Array + +Medium + +You are given an integer array `nums`. This array contains `n` elements, where **exactly** `n - 2` elements are **special** **numbers**. One of the remaining **two** elements is the _sum_ of these **special numbers**, and the other is an **outlier**. + +An **outlier** is defined as a number that is _neither_ one of the original special numbers _nor_ the element representing the sum of those numbers. + +**Note** that special numbers, the sum element, and the outlier must have **distinct** indices, but _may_ share the **same** value. + +Return the **largest** potential **outlier** in `nums`. + +**Example 1:** + +**Input:** nums = [2,3,5,10] + +**Output:** 10 + +**Explanation:** + +The special numbers could be 2 and 3, thus making their sum 5 and the outlier 10. + +**Example 2:** + +**Input:** nums = [-2,-1,-3,-6,4] + +**Output:** 4 + +**Explanation:** + +The special numbers could be -2, -1, and -3, thus making their sum -6 and the outlier 4. + +**Example 3:** + +**Input:** nums = [1,1,1,1,1,5,5] + +**Output:** 5 + +**Explanation:** + +The special numbers could be 1, 1, 1, 1, and 1, thus making their sum 5 and the other 5 as the outlier. + +**Constraints:** + +* 3 <= nums.length <= 105 +* `-1000 <= nums[i] <= 1000` +* The input is generated such that at least **one** potential outlier exists in `nums`. \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/Solution.java b/src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/Solution.java new file mode 100644 index 000000000..1eddea100 --- /dev/null +++ b/src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/Solution.java @@ -0,0 +1,68 @@ +package g3301_3400.s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i; + +// #Medium #2024_12_01_Time_828_ms_(100.00%)_Space_47.8_MB_(100.00%) + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Queue; + +public class Solution { + private void bfs(ArrayList> tree, int node, int[] arr, int k) { + Queue q = new LinkedList<>(); + HashSet visited = new HashSet<>(); + q.add(node); + int count = 0; + while (!q.isEmpty() && count <= k) { + int size = q.size(); + for (int i = 0; i < size; i++) { + int temp = q.poll(); + visited.add(temp); + for (int x : tree.get(temp)) { + if (!visited.contains(x)) { + q.offer(x); + } + } + } + count++; + } + arr[node] = visited.size(); + } + + public int[] maxTargetNodes(int[][] edges1, int[][] edges2, int k) { + int n = edges1.length + 1; + int m = edges2.length + 1; + ArrayList> tree1 = new ArrayList<>(); + ArrayList> tree2 = new ArrayList<>(); + for (int i = 0; i < n; i++) { + tree1.add(new ArrayList<>()); + } + for (int i = 0; i < m; i++) { + tree2.add(new ArrayList<>()); + } + for (int[] e : edges1) { + tree1.get(e[0]).add(e[1]); + tree1.get(e[1]).add(e[0]); + } + for (int[] e : edges2) { + tree2.get(e[0]).add(e[1]); + tree2.get(e[1]).add(e[0]); + } + int[] tar1 = new int[n]; + int[] tar2 = new int[m]; + for (int i = 0; i < m; i++) { + bfs(tree2, i, tar2, k - 1); + } + int max = 0; + for (int i : tar2) { + max = Math.max(i, max); + } + for (int i = 0; i < n; i++) { + bfs(tree1, i, tar1, k); + } + for (int i = 0; i < n; i++) { + tar1[i] += max; + } + return tar1; + } +} diff --git a/src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/readme.md b/src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/readme.md new file mode 100644 index 000000000..565624f04 --- /dev/null +++ b/src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/readme.md @@ -0,0 +1,54 @@ +3372\. Maximize the Number of Target Nodes After Connecting Trees I + +Medium + +There exist two **undirected** trees with `n` and `m` nodes, with **distinct** labels in ranges `[0, n - 1]` and `[0, m - 1]`, respectively. + +You are given two 2D integer arrays `edges1` and `edges2` of lengths `n - 1` and `m - 1`, respectively, where edges1[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the first tree and edges2[i] = [ui, vi] indicates that there is an edge between nodes ui and vi in the second tree. You are also given an integer `k`. + +Node `u` is **target** to node `v` if the number of edges on the path from `u` to `v` is less than or equal to `k`. **Note** that a node is _always_ **target** to itself. + +Return an array of `n` integers `answer`, where `answer[i]` is the **maximum** possible number of nodes **target** to node `i` of the first tree if you have to connect one node from the first tree to another node in the second tree. + +**Note** that queries are independent from each other. That is, for every query you will remove the added edge before proceeding to the next query. + +**Example 1:** + +**Input:** edges1 = [[0,1],[0,2],[2,3],[2,4]], edges2 = [[0,1],[0,2],[0,3],[2,7],[1,4],[4,5],[4,6]], k = 2 + +**Output:** [9,7,9,8,8] + +**Explanation:** + +* For `i = 0`, connect node 0 from the first tree to node 0 from the second tree. +* For `i = 1`, connect node 1 from the first tree to node 0 from the second tree. +* For `i = 2`, connect node 2 from the first tree to node 4 from the second tree. +* For `i = 3`, connect node 3 from the first tree to node 4 from the second tree. +* For `i = 4`, connect node 4 from the first tree to node 4 from the second tree. + +![](https://assets.leetcode.com/uploads/2024/09/24/3982-1.png) + +**Example 2:** + +**Input:** edges1 = [[0,1],[0,2],[0,3],[0,4]], edges2 = [[0,1],[1,2],[2,3]], k = 1 + +**Output:** [6,3,3,3,3] + +**Explanation:** + +For every `i`, connect node `i` of the first tree with any node of the second tree. + +![](https://assets.leetcode.com/uploads/2024/09/24/3928-2.png) + +**Constraints:** + +* `2 <= n, m <= 1000` +* `edges1.length == n - 1` +* `edges2.length == m - 1` +* `edges1[i].length == edges2[i].length == 2` +* edges1[i] = [ai, bi] +* 0 <= ai, bi < n +* edges2[i] = [ui, vi] +* 0 <= ui, vi < m +* The input is generated such that `edges1` and `edges2` represent valid trees. +* `0 <= k <= 1000` \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java b/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java new file mode 100644 index 000000000..c3ca5c2a7 --- /dev/null +++ b/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java @@ -0,0 +1,85 @@ +package g3301_3400.s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii; + +// #Hard #2024_12_01_Time_447_ms_(100.00%)_Space_173.2_MB_(100.00%) + +import java.util.HashMap; +import java.util.HashSet; + +public class Solution { + private int dfs(int a, HashMap> adj, boolean[] mark, int i) { + int res = 0; + mark[a] = true; + if (i % 2 == 0) { + res++; + } + for (int j : adj.get(a)) { + if (!mark[j]) { + res += dfs(j, adj, mark, i + 1); + } + } + return res; + } + + private void sol( + int a, + HashMap> adj, + boolean[] mark, + int i, + int t, + int n, + int[] res) { + mark[a] = true; + if (i % 2 == 0) { + res[a] = t; + } else { + res[a] = n - t; + } + for (int j : adj.get(a)) { + if (!mark[j]) { + sol(j, adj, mark, i + 1, t, n, res); + } + } + } + + public int[] maxTargetNodes(int[][] edges1, int[][] edges2) { + int n = edges1.length + 1; + int m = edges2.length + 1; + HashMap> adj1 = new HashMap<>(); + HashMap> adj2 = new HashMap<>(); + for (int[] i : edges1) { + if (adj1.get(i[0]) == null) { + adj1.put(i[0], new HashSet<>()); + } + adj1.get(i[0]).add(i[1]); + if (adj1.get(i[1]) == null) { + adj1.put(i[1], new HashSet<>()); + } + adj1.get(i[1]).add(i[0]); + } + for (int[] i : edges2) { + if (adj2.get(i[0]) == null) { + adj2.put(i[0], new HashSet<>()); + } + adj2.get(i[0]).add(i[1]); + if (adj2.get(i[1]) == null) { + adj2.put(i[1], new HashSet<>()); + } + adj2.get(i[1]).add(i[0]); + } + boolean[] mark1 = new boolean[n]; + boolean[] mark2 = new boolean[m]; + int a = dfs(0, adj2, mark2, 0); + int b = dfs(0, adj1, mark1, 0); + mark1 = new boolean[n]; + int[] res = new int[n]; + sol(0, adj1, mark1, 0, b, n, res); + for (int i = 0; i < res.length; i++) { + if (res[i] != n) { + res[i] += Math.max(a, m - a); + } else { + res[i] += a; + } + } + return res; + } +} diff --git a/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/readme.md b/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/readme.md new file mode 100644 index 000000000..3558c9474 --- /dev/null +++ b/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/readme.md @@ -0,0 +1,53 @@ +3373\. Maximize the Number of Target Nodes After Connecting Trees II + +Hard + +There exist two **undirected** trees with `n` and `m` nodes, labeled from `[0, n - 1]` and `[0, m - 1]`, respectively. + +You are given two 2D integer arrays `edges1` and `edges2` of lengths `n - 1` and `m - 1`, respectively, where edges1[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the first tree and edges2[i] = [ui, vi] indicates that there is an edge between nodes ui and vi in the second tree. + +Node `u` is **target** to node `v` if the number of edges on the path from `u` to `v` is even. **Note** that a node is _always_ **target** to itself. + +Return an array of `n` integers `answer`, where `answer[i]` is the **maximum** possible number of nodes that are **target** to node `i` of the first tree if you had to connect one node from the first tree to another node in the second tree. + +**Note** that queries are independent from each other. That is, for every query you will remove the added edge before proceeding to the next query. + +**Example 1:** + +**Input:** edges1 = [[0,1],[0,2],[2,3],[2,4]], edges2 = [[0,1],[0,2],[0,3],[2,7],[1,4],[4,5],[4,6]] + +**Output:** [8,7,7,8,8] + +**Explanation:** + +* For `i = 0`, connect node 0 from the first tree to node 0 from the second tree. +* For `i = 1`, connect node 1 from the first tree to node 4 from the second tree. +* For `i = 2`, connect node 2 from the first tree to node 7 from the second tree. +* For `i = 3`, connect node 3 from the first tree to node 0 from the second tree. +* For `i = 4`, connect node 4 from the first tree to node 4 from the second tree. + +![](https://assets.leetcode.com/uploads/2024/09/24/3982-1.png) + +**Example 2:** + +**Input:** edges1 = [[0,1],[0,2],[0,3],[0,4]], edges2 = [[0,1],[1,2],[2,3]] + +**Output:** [3,6,6,6,6] + +**Explanation:** + +For every `i`, connect node `i` of the first tree with any node of the second tree. + +![](https://assets.leetcode.com/uploads/2024/09/24/3928-2.png) + +**Constraints:** + +* 2 <= n, m <= 105 +* `edges1.length == n - 1` +* `edges2.length == m - 1` +* `edges1[i].length == edges2[i].length == 2` +* edges1[i] = [ai, bi] +* 0 <= ai, bi < n +* edges2[i] = [ui, vi] +* 0 <= ui, vi < m +* The input is generated such that `edges1` and `edges2` represent valid trees. \ No newline at end of file diff --git a/src/test/java/g3301_3400/s3370_smallest_number_with_all_set_bits/SolutionTest.java b/src/test/java/g3301_3400/s3370_smallest_number_with_all_set_bits/SolutionTest.java new file mode 100644 index 000000000..b907da72d --- /dev/null +++ b/src/test/java/g3301_3400/s3370_smallest_number_with_all_set_bits/SolutionTest.java @@ -0,0 +1,23 @@ +package g3301_3400.s3370_smallest_number_with_all_set_bits; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void smallestNumber() { + assertThat(new Solution().smallestNumber(5), equalTo(7)); + } + + @Test + void smallestNumber2() { + assertThat(new Solution().smallestNumber(10), equalTo(15)); + } + + @Test + void smallestNumber3() { + assertThat(new Solution().smallestNumber(3), equalTo(3)); + } +} diff --git a/src/test/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/SolutionTest.java b/src/test/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/SolutionTest.java new file mode 100644 index 000000000..8b882bc33 --- /dev/null +++ b/src/test/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/SolutionTest.java @@ -0,0 +1,23 @@ +package g3301_3400.s3371_identify_the_largest_outlier_in_an_array; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void getLargestOutlier() { + assertThat(new Solution().getLargestOutlier(new int[] {2, 3, 5, 10}), equalTo(10)); + } + + @Test + void getLargestOutlier2() { + assertThat(new Solution().getLargestOutlier(new int[] {-2, -1, -3, -6, 4}), equalTo(4)); + } + + @Test + void getLargestOutlier3() { + assertThat(new Solution().getLargestOutlier(new int[] {1, 1, 1, 1, 1, 5, 5}), equalTo(5)); + } +} diff --git a/src/test/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/SolutionTest.java b/src/test/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/SolutionTest.java new file mode 100644 index 000000000..f61782f91 --- /dev/null +++ b/src/test/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/SolutionTest.java @@ -0,0 +1,32 @@ +package g3301_3400.s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxTargetNodes() { + assertThat( + new Solution() + .maxTargetNodes( + new int[][] {{0, 1}, {0, 2}, {2, 3}, {2, 4}}, + new int[][] { + {0, 1}, {0, 2}, {0, 3}, {2, 7}, {1, 4}, {4, 5}, {4, 6} + }, + 2), + equalTo(new int[] {9, 7, 9, 8, 8})); + } + + @Test + void maxTargetNodes2() { + assertThat( + new Solution() + .maxTargetNodes( + new int[][] {{0, 1}, {0, 2}, {0, 3}, {0, 4}}, + new int[][] {{0, 1}, {1, 2}, {2, 3}}, + 1), + equalTo(new int[] {6, 3, 3, 3, 3})); + } +} diff --git a/src/test/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/SolutionTest.java b/src/test/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/SolutionTest.java new file mode 100644 index 000000000..601a6d7be --- /dev/null +++ b/src/test/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/SolutionTest.java @@ -0,0 +1,30 @@ +package g3301_3400.s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxTargetNodes() { + assertThat( + new Solution() + .maxTargetNodes( + new int[][] {{0, 1}, {0, 2}, {2, 3}, {2, 4}}, + new int[][] { + {0, 1}, {0, 2}, {0, 3}, {2, 7}, {1, 4}, {4, 5}, {4, 6} + }), + equalTo(new int[] {8, 7, 7, 8, 8})); + } + + @Test + void maxTargetNodes2() { + assertThat( + new Solution() + .maxTargetNodes( + new int[][] {{0, 1}, {0, 2}, {0, 3}, {0, 4}}, + new int[][] {{0, 1}, {1, 2}, {2, 3}}), + equalTo(new int[] {3, 6, 6, 6, 6})); + } +} From 17af234509066a98c5576a468747c61a4c681229 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 3 Dec 2024 02:58:54 +0200 Subject: [PATCH 08/16] Improved tasks 3360-3373 --- .../s3360_stone_removal_game/Solution.java | 2 +- .../Solution.java | 42 ++++--- .../Solution.java | 3 +- .../Solution.java | 2 +- .../Solution.java | 27 ++-- .../Solution.java | 2 +- .../s3366_minimum_array_sum/Solution.java | 87 +++++++++---- .../Solution.java | 3 +- .../Solution.java | 2 +- .../Solution.java | 41 +++--- .../Solution.java | 117 +++++++++-------- .../Solution.java | 119 ++++++++---------- 12 files changed, 249 insertions(+), 198 deletions(-) diff --git a/src/main/java/g3301_3400/s3360_stone_removal_game/Solution.java b/src/main/java/g3301_3400/s3360_stone_removal_game/Solution.java index d8bc45ded..5dc9f2ee8 100644 --- a/src/main/java/g3301_3400/s3360_stone_removal_game/Solution.java +++ b/src/main/java/g3301_3400/s3360_stone_removal_game/Solution.java @@ -1,6 +1,6 @@ package g3301_3400.s3360_stone_removal_game; -// #Easy #2024_11_24_Time_0_ms_(100.00%)_Space_40.5_MB_(100.00%) +// #Easy #Math #Simulation #2024_12_03_Time_0_ms_(100.00%)_Space_40.3_MB_(80.86%) public class Solution { public boolean canAliceWin(int n) { diff --git a/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java b/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java index c25bc4cee..1cb409df2 100644 --- a/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java +++ b/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java @@ -1,26 +1,36 @@ package g3301_3400.s3361_shift_distance_between_two_strings; -// #Medium #2024_11_24_Time_57_ms_(100.00%)_Space_45.7_MB_(100.00%) +// #Medium #Array #String #Prefix_Sum #2024_12_03_Time_9_ms_(100.00%)_Space_45.8_MB_(36.02%) public class Solution { public long shiftDistance(String s, String t, int[] nextCost, int[] previousCost) { - long sum = 0; - int n = s.length(); - for (int i = 0; i < n; i++) { - int ch1 = s.charAt(i) - 'a'; - int ch2 = t.charAt(i) - 'a'; - int forwardDiff = (ch2 - ch1 + 26) % 26; - long forwardCost = 0; - for (int j = 0; j < forwardDiff; j++) { - forwardCost += nextCost[(ch1 + j) % 26]; + long[][] costs = new long[26][26]; + long cost; + for (int i = 0; i < 26; i++) { + cost = nextCost[i]; + for (int j = (i == 25 ? 0 : i + 1); j != i; j++) { + costs[i][j] = cost; + cost += nextCost[j]; + if (j == 25) { + j = -1; + } } - int reverseDiff = (26 + ch1 - ch2) % 26; - long backwardCost = 0; - for (int j = 0; j < reverseDiff; j++) { - backwardCost += previousCost[(ch1 - j + 26) % 26]; + } + for (int i = 0; i < 26; i++) { + cost = previousCost[i]; + for (int j = (i == 0 ? 25 : i - 1); j != i; j--) { + costs[i][j] = Math.min(costs[i][j], cost); + cost += previousCost[j]; + if (j == 0) { + j = 26; + } } - sum += Math.min(forwardCost, backwardCost); } - return sum; + int n = s.length(); + long ans = 0; + for (int i = 0; i < n; i++) { + ans += costs[s.charAt(i) - 'a'][t.charAt(i) - 'a']; + } + return ans; } } diff --git a/src/main/java/g3301_3400/s3362_zero_array_transformation_iii/Solution.java b/src/main/java/g3301_3400/s3362_zero_array_transformation_iii/Solution.java index 82de6fe21..3fc46add3 100644 --- a/src/main/java/g3301_3400/s3362_zero_array_transformation_iii/Solution.java +++ b/src/main/java/g3301_3400/s3362_zero_array_transformation_iii/Solution.java @@ -1,6 +1,7 @@ package g3301_3400.s3362_zero_array_transformation_iii; -// #Medium #2024_11_24_Time_67_ms_(100.00%)_Space_89.9_MB_(66.67%) +// #Medium #Array #Sorting #Greedy #Heap_Priority_Queue #Prefix_Sum +// #2024_12_03_Time_68_ms_(91.99%)_Space_93.6_MB_(45.88%) import java.util.Arrays; import java.util.PriorityQueue; diff --git a/src/main/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/Solution.java b/src/main/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/Solution.java index bf4e60b0f..97ccaa735 100644 --- a/src/main/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/Solution.java +++ b/src/main/java/g3301_3400/s3363_find_the_maximum_number_of_fruits_collected/Solution.java @@ -1,6 +1,6 @@ package g3301_3400.s3363_find_the_maximum_number_of_fruits_collected; -// #Hard #2024_11_24_Time_13_ms_(100.00%)_Space_142.3_MB_(33.33%) +// #Hard #Array #Dynamic_Programming #Matrix #2024_12_03_Time_12_ms_(91.34%)_Space_142.1_MB_(88.96%) public class Solution { public int maxCollectedFruits(int[][] fruits) { diff --git a/src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/Solution.java b/src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/Solution.java index 3d027702f..54104ec04 100644 --- a/src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/Solution.java +++ b/src/main/java/g3301_3400/s3364_minimum_positive_sum_subarray/Solution.java @@ -1,24 +1,25 @@ package g3301_3400.s3364_minimum_positive_sum_subarray; -// #Easy #2024_11_24_Time_28_ms_(100.00%)_Space_44.7_MB_(100.00%) +// #Easy #Array #Prefix_Sum #Sliding_Window #2024_12_03_Time_1_ms_(100.00%)_Space_44.5_MB_(38.75%) import java.util.List; public class Solution { - public int minimumSumSubarray(List nums, int l, int r) { - int size = nums.size(); - int res = -1; - for (int s = l; s <= r; s++) { - for (int i = 0; i <= size - s; i++) { - int sum = 0; - for (int j = i; j < i + s; j++) { - sum += nums.get(j); - } - if (sum > 0 && (res == -1 || res > sum)) { - res = sum; + public int minimumSumSubarray(List li, int l, int r) { + int n = li.size(); + int min = Integer.MAX_VALUE; + int[] a = new int[n + 1]; + for (int i = 1; i <= n; i++) { + a[i] = a[i - 1] + li.get(i - 1); + } + for (int size = l; size <= r; size++) { + for (int i = size - 1; i < n; i++) { + int sum = a[i + 1] - a[i + 1 - size]; + if (sum > 0) { + min = Math.min(min, sum); } } } - return res; + return min == Integer.MAX_VALUE ? -1 : min; } } diff --git a/src/main/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/Solution.java b/src/main/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/Solution.java index 5c14fabae..50e7923ff 100644 --- a/src/main/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/Solution.java +++ b/src/main/java/g3301_3400/s3365_rearrange_k_substrings_to_form_target_string/Solution.java @@ -1,6 +1,6 @@ package g3301_3400.s3365_rearrange_k_substrings_to_form_target_string; -// #Medium #2024_11_24_Time_61_ms_(100.00%)_Space_49.3_MB_(100.00%) +// #Medium #String #Hash_Table #Sorting #2024_12_03_Time_59_ms_(94.24%)_Space_49.2_MB_(97.33%) import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java b/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java index b4e5ecf7b..bd21f28f2 100644 --- a/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java +++ b/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java @@ -1,38 +1,75 @@ package g3301_3400.s3366_minimum_array_sum; -// #Medium #2024_11_24_Time_66_ms_(100.00%)_Space_55_MB_(100.00%) +// #Medium #Array #Dynamic_Programming #2024_12_03_Time_4_ms_(99.77%)_Space_43_MB_(99.69%) + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; public class Solution { public int minArraySum(int[] nums, int k, int op1, int op2) { - Integer[][][] dp = new Integer[nums.length][op1 + 1][op2 + 1]; - return sub(dp, nums, 0, k, op1, op2); - } - - private int sub(Integer[][][] dp, int[] nums, int i, int k, int op1, int op2) { - if (i == nums.length) { - return 0; - } - if (dp[i][op1][op2] != null) { - return dp[i][op1][op2]; + Arrays.sort(nums); + int high = lowerBound(nums, k * 2 - 1); + int low = lowerBound(nums, k); + int n = nums.length; + for (int i = n - 1; i >= high; i--) { + if (op1 > 0) { + nums[i] = (nums[i] + 1) / 2; + op1--; + } + if (op2 > 0) { + nums[i] -= k; + op2--; + } } - int res = sub(dp, nums, i + 1, k, op1, op2) + nums[i]; - if (nums[i] >= k && op2 > 0) { - res = Math.min(res, sub(dp, nums, i + 1, k, op1, op2 - 1) + nums[i] - k); - int v = (int) Math.ceil(nums[i] / 2.0); - if (v < k) { - v = (int) Math.ceil((nums[i] - k) / 2.0); + Map count = new HashMap<>(); + int odd = 0; + for (int i = low; i < high; i++) { + if (op2 > 0) { + nums[i] -= k; + if (k % 2 > 0 && nums[i] % 2 > 0) { + count.merge(nums[i], 1, Integer::sum); + } + op2--; } else { - v -= k; + odd += nums[i] % 2; } - if (op1 > 0) { - res = Math.min(res, sub(dp, nums, i + 1, k, op1 - 1, op2 - 1) + v); + } + Arrays.sort(nums, 0, high); + int ans = 0; + if (k % 2 > 0) { + for (int i = high - op1; i < high && odd > 0; i++) { + int x = nums[i]; + if (count.containsKey(x)) { + if (count.merge(x, -1, Integer::sum) == 0) { + count.remove(x); + } + odd--; + ans--; + } } } - if (op1 > 0) { - int v = (int) Math.ceil(nums[i] / 2.0); - res = Math.min(res, sub(dp, nums, i + 1, k, op1 - 1, op2) + v); + for (int i = high - 1; i >= 0 && op1 > 0; i--) { + nums[i] = (nums[i] + 1) / 2; + op1--; + } + for (int x : nums) { + ans += x; + } + return ans; + } + + private int lowerBound(int[] nums, int target) { + int left = -1; + int right = nums.length; + while (left + 1 < right) { + int mid = (left + right) >>> 1; + if (nums[mid] >= target) { + right = mid; + } else { + left = mid; + } } - dp[i][op1][op2] = res; - return res; + return right; } } diff --git a/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java b/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java index 766d66e17..e7f21530b 100644 --- a/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java +++ b/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java @@ -1,6 +1,7 @@ package g3301_3400.s3367_maximize_sum_of_weights_after_edge_removals; -// #Hard #2024_11_27_Time_87_ms_(98.35%)_Space_152.7_MB_(18.13%) +// #Hard #Dynamic_Programming #Tree #Depth_First_Search +// #2024_12_03_Time_104_ms_(91.49%)_Space_147.1_MB_(58.51%) import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/g3301_3400/s3370_smallest_number_with_all_set_bits/Solution.java b/src/main/java/g3301_3400/s3370_smallest_number_with_all_set_bits/Solution.java index b4668d1c6..e6aa88a88 100644 --- a/src/main/java/g3301_3400/s3370_smallest_number_with_all_set_bits/Solution.java +++ b/src/main/java/g3301_3400/s3370_smallest_number_with_all_set_bits/Solution.java @@ -1,6 +1,6 @@ package g3301_3400.s3370_smallest_number_with_all_set_bits; -// #Easy #2024_12_01_Time_0_ms_(100.00%)_Space_40.7_MB_(100.00%) +// #Easy #Math #Bit_Manipulation #2024_12_03_Time_0_ms_(100.00%)_Space_41.1_MB_(45.50%) public class Solution { public int smallestNumber(int n) { diff --git a/src/main/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/Solution.java b/src/main/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/Solution.java index 430801b34..7756407e9 100644 --- a/src/main/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/Solution.java +++ b/src/main/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/Solution.java @@ -1,33 +1,30 @@ package g3301_3400.s3371_identify_the_largest_outlier_in_an_array; -// #Medium #2024_12_01_Time_633_ms_(100.00%)_Space_64.5_MB_(100.00%) - -import java.util.TreeMap; +// #Medium #Array #Hash_Table #Counting #Enumeration +// #2024_12_03_Time_5_ms_(100.00%)_Space_60.6_MB_(33.40%) public class Solution { public int getLargestOutlier(int[] nums) { + int[] cnt = new int[2001]; int sum = 0; - for (int num : nums) { - sum += num; - } - TreeMap frequencyMap = new TreeMap<>(); - for (int num : nums) { - frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1); + for (int i : nums) { + sum += i; + cnt[i + 1000]++; } - int ans = Integer.MIN_VALUE; - for (int num : nums) { - if ((sum - num) % 2 == 0) { - int target = (sum - num) / 2; - frequencyMap.put(num, frequencyMap.get(num) - 1); - if (frequencyMap.get(num) == 0) { - frequencyMap.remove(num); - } - if (frequencyMap.containsKey(target)) { - ans = Math.max(ans, num); - } - frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1); + for (int i = cnt.length - 1; i >= 0; --i) { + int j = i - 1000; + if (cnt[i] == 0) { + continue; + } + sum -= j; + int csum = (sum >> 1) + 1000; + cnt[i]--; + if (sum % 2 == 0 && csum >= 0 && csum < cnt.length && cnt[csum] > 0) { + return j; } + sum += j; + cnt[i]++; } - return ans == Integer.MIN_VALUE ? -1 : ans; + return 0; } } diff --git a/src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/Solution.java b/src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/Solution.java index 1eddea100..f553f6a4e 100644 --- a/src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/Solution.java +++ b/src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/Solution.java @@ -1,68 +1,87 @@ package g3301_3400.s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i; -// #Medium #2024_12_01_Time_828_ms_(100.00%)_Space_47.8_MB_(100.00%) +// #Medium #Tree #Depth_First_Search #Breadth_First_Search +// #2024_12_03_Time_50_ms_(99.49%)_Space_75.7_MB_(5.10%) import java.util.ArrayList; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Queue; +@SuppressWarnings("unchecked") public class Solution { - private void bfs(ArrayList> tree, int node, int[] arr, int k) { - Queue q = new LinkedList<>(); - HashSet visited = new HashSet<>(); - q.add(node); - int count = 0; - while (!q.isEmpty() && count <= k) { - int size = q.size(); - for (int i = 0; i < size; i++) { - int temp = q.poll(); - visited.add(temp); - for (int x : tree.get(temp)) { - if (!visited.contains(x)) { - q.offer(x); - } - } - } - count++; + private ArrayList[] getGraph(int[][] edges) { + int n = edges.length + 1; + ArrayList[] graph = new ArrayList[n]; + for (int i = 0; i < n; i++) { + graph[i] = new ArrayList<>(); + } + for (int[] edge : edges) { + int u = edge[0]; + int v = edge[1]; + graph[u].add(v); + graph[v].add(u); } - arr[node] = visited.size(); + return graph; } - public int[] maxTargetNodes(int[][] edges1, int[][] edges2, int k) { - int n = edges1.length + 1; - int m = edges2.length + 1; - ArrayList> tree1 = new ArrayList<>(); - ArrayList> tree2 = new ArrayList<>(); - for (int i = 0; i < n; i++) { - tree1.add(new ArrayList<>()); - } - for (int i = 0; i < m; i++) { - tree2.add(new ArrayList<>()); + private void dfs(ArrayList[] graph, int u, int pt, int[][] dp, int k) { + for (int v : graph[u]) { + if (v == pt) { + continue; + } + dfs(graph, v, u, dp, k); + for (int i = 0; i < k; i++) { + dp[u][i + 1] += dp[v][i]; + } } - for (int[] e : edges1) { - tree1.get(e[0]).add(e[1]); - tree1.get(e[1]).add(e[0]); + dp[u][0]++; + } + + private void dfs2( + ArrayList[] graph, int u, int pt, int[] ptv, int[][] fdp, int[][] dp, int k) { + fdp[u][0] = dp[u][0]; + for (int i = 1; i <= k; i++) { + fdp[u][i] = (dp[u][i] + ptv[i - 1]); } - for (int[] e : edges2) { - tree2.get(e[0]).add(e[1]); - tree2.get(e[1]).add(e[0]); + for (int v : graph[u]) { + if (v == pt) { + continue; + } + int[] nptv = new int[k + 1]; + for (int i = 0; i < k; i++) { + nptv[i + 1] = dp[u][i + 1] - dp[v][i] + ptv[i]; + } + nptv[0] = 1; + dfs2(graph, v, u, nptv, fdp, dp, k); } - int[] tar1 = new int[n]; - int[] tar2 = new int[m]; - for (int i = 0; i < m; i++) { - bfs(tree2, i, tar2, k - 1); + } + + private int[][] get(int[][] edges, int k) { + ArrayList[] graph = getGraph(edges); + int n = graph.length; + int[][] dp = new int[n][k + 1]; + int[][] fdp = new int[n][k + 1]; + dfs(graph, 0, -1, dp, k); + dfs2(graph, 0, -1, new int[k + 1], fdp, dp, k); + for (int i = 0; i < n; i++) { + for (int j = 1; j <= k; j++) { + fdp[i][j] += fdp[i][j - 1]; + } } + return fdp; + } + + public int[] maxTargetNodes(int[][] edges1, int[][] edges2, int k) { + int[][] a = get(edges1, k); + int[][] b = get(edges2, k); + int n = a.length; + int m = b.length; + int[] ans = new int[n]; int max = 0; - for (int i : tar2) { - max = Math.max(i, max); - } - for (int i = 0; i < n; i++) { - bfs(tree1, i, tar1, k); + for (int i = 0; k != 0 && i < m; i++) { + max = Math.max(max, b[i][k - 1]); } for (int i = 0; i < n; i++) { - tar1[i] += max; + ans[i] = a[i][k] + max; } - return tar1; + return ans; } } diff --git a/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java b/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java index c3ca5c2a7..e2fc2b8ce 100644 --- a/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java +++ b/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java @@ -1,85 +1,70 @@ package g3301_3400.s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii; -// #Hard #2024_12_01_Time_447_ms_(100.00%)_Space_173.2_MB_(100.00%) +// #Hard #Tree #Depth_First_Search #Breadth_First_Search +// #2024_12_03_Time_26_ms_(98.75%)_Space_114.7_MB_(80.00%) -import java.util.HashMap; -import java.util.HashSet; +import java.util.Arrays; public class Solution { - private int dfs(int a, HashMap> adj, boolean[] mark, int i) { - int res = 0; - mark[a] = true; - if (i % 2 == 0) { - res++; + public int[] maxTargetNodes(int[][] edges1, int[][] edges2) { + int n = edges1.length + 1; + int[][] g1 = packU(n, edges1); + int m = edges2.length + 1; + int[][] g2 = packU(m, edges2); + + int[][] p2 = parents(g2, 0); + int[] eo2 = new int[2]; + for (int i = 0; i < m; i++) { + eo2[p2[2][i] % 2]++; } - for (int j : adj.get(a)) { - if (!mark[j]) { - res += dfs(j, adj, mark, i + 1); - } + int max = Math.max(eo2[0], eo2[1]); + int[][] p1 = parents(g1, 0); + int[] eo1 = new int[2]; + for (int i = 0; i < n; i++) { + eo1[p1[2][i] % 2]++; + } + int[] ans = new int[n]; + for (int i = 0; i < n; i++) { + ans[i] = eo1[p1[2][i] % 2] + max; } - return res; + return ans; } - private void sol( - int a, - HashMap> adj, - boolean[] mark, - int i, - int t, - int n, - int[] res) { - mark[a] = true; - if (i % 2 == 0) { - res[a] = t; - } else { - res[a] = n - t; - } - for (int j : adj.get(a)) { - if (!mark[j]) { - sol(j, adj, mark, i + 1, t, n, res); + private int[][] parents(int[][] g, int root) { + int n = g.length; + int[] par = new int[n]; + Arrays.fill(par, -1); + int[] depth = new int[n]; + depth[0] = 0; + int[] q = new int[n]; + q[0] = root; + for (int p = 0, r = 1; p < r; p++) { + int cur = q[p]; + for (int nex : g[cur]) { + if (par[cur] != nex) { + q[r++] = nex; + par[nex] = cur; + depth[nex] = depth[cur] + 1; + } } } + return new int[][] {par, q, depth}; } - public int[] maxTargetNodes(int[][] edges1, int[][] edges2) { - int n = edges1.length + 1; - int m = edges2.length + 1; - HashMap> adj1 = new HashMap<>(); - HashMap> adj2 = new HashMap<>(); - for (int[] i : edges1) { - if (adj1.get(i[0]) == null) { - adj1.put(i[0], new HashSet<>()); - } - adj1.get(i[0]).add(i[1]); - if (adj1.get(i[1]) == null) { - adj1.put(i[1], new HashSet<>()); - } - adj1.get(i[1]).add(i[0]); + private int[][] packU(int n, int[][] ft) { + int[][] g = new int[n][]; + int[] p = new int[n]; + for (int[] u : ft) { + p[u[0]]++; + p[u[1]]++; } - for (int[] i : edges2) { - if (adj2.get(i[0]) == null) { - adj2.put(i[0], new HashSet<>()); - } - adj2.get(i[0]).add(i[1]); - if (adj2.get(i[1]) == null) { - adj2.put(i[1], new HashSet<>()); - } - adj2.get(i[1]).add(i[0]); + for (int i = 0; i < n; i++) { + g[i] = new int[p[i]]; } - boolean[] mark1 = new boolean[n]; - boolean[] mark2 = new boolean[m]; - int a = dfs(0, adj2, mark2, 0); - int b = dfs(0, adj1, mark1, 0); - mark1 = new boolean[n]; - int[] res = new int[n]; - sol(0, adj1, mark1, 0, b, n, res); - for (int i = 0; i < res.length; i++) { - if (res[i] != n) { - res[i] += Math.max(a, m - a); - } else { - res[i] += a; - } + for (int[] u : ft) { + g[u[0]][--p[u[0]]] = u[1]; + g[u[1]][--p[u[1]]] = u[0]; } - return res; + return g; } } From fee13d399dcacb730c94419ccfbb614038c1365d Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 3 Dec 2024 03:05:14 +0200 Subject: [PATCH 09/16] Fixed sonar --- .../s3361_shift_distance_between_two_strings/Solution.java | 4 +++- .../java/g3301_3400/s3366_minimum_array_sum/Solution.java | 3 +-- .../Solution.java | 5 ++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java b/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java index 1cb409df2..c32d2cfba 100644 --- a/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java +++ b/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java @@ -18,12 +18,14 @@ public long shiftDistance(String s, String t, int[] nextCost, int[] previousCost } for (int i = 0; i < 26; i++) { cost = previousCost[i]; - for (int j = (i == 0 ? 25 : i - 1); j != i; j--) { + int j = i == 0 ? 25 : i - 1; + while (j != i) { costs[i][j] = Math.min(costs[i][j], cost); cost += previousCost[j]; if (j == 0) { j = 26; } + j--; } } int n = s.length(); diff --git a/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java b/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java index bd21f28f2..a667ee6e5 100644 --- a/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java +++ b/src/main/java/g3301_3400/s3366_minimum_array_sum/Solution.java @@ -49,9 +49,8 @@ public int minArraySum(int[] nums, int k, int op1, int op2) { } } } - for (int i = high - 1; i >= 0 && op1 > 0; i--) { + for (int i = high - 1; i >= 0 && op1 > 0; i--, op1--) { nums[i] = (nums[i] + 1) / 2; - op1--; } for (int x : nums) { ans += x; diff --git a/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java b/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java index e2fc2b8ce..f5982b6b2 100644 --- a/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java +++ b/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java @@ -38,7 +38,9 @@ private int[][] parents(int[][] g, int root) { depth[0] = 0; int[] q = new int[n]; q[0] = root; - for (int p = 0, r = 1; p < r; p++) { + int p = 0; + int r = 1; + while (p < r) { int cur = q[p]; for (int nex : g[cur]) { if (par[cur] != nex) { @@ -47,6 +49,7 @@ private int[][] parents(int[][] g, int root) { depth[nex] = depth[cur] + 1; } } + p++; } return new int[][] {par, q, depth}; } From d54ae4880c83cc6f2bce280ad370475ee3165ec7 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 3 Dec 2024 03:06:04 +0200 Subject: [PATCH 10/16] Fixed format --- .../Solution.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java b/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java index f5982b6b2..e57582c82 100644 --- a/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java +++ b/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java @@ -11,7 +11,6 @@ public int[] maxTargetNodes(int[][] edges1, int[][] edges2) { int[][] g1 = packU(n, edges1); int m = edges2.length + 1; int[][] g2 = packU(m, edges2); - int[][] p2 = parents(g2, 0); int[] eo2 = new int[2]; for (int i = 0; i < m; i++) { From ebe0fa52a3d51690d8cddc2af118493aa4db872a Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 3 Dec 2024 03:06:57 +0200 Subject: [PATCH 11/16] Fixed idea --- .../Solution.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java b/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java index e57582c82..18ae7cccd 100644 --- a/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java +++ b/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java @@ -11,13 +11,13 @@ public int[] maxTargetNodes(int[][] edges1, int[][] edges2) { int[][] g1 = packU(n, edges1); int m = edges2.length + 1; int[][] g2 = packU(m, edges2); - int[][] p2 = parents(g2, 0); + int[][] p2 = parents(g2); int[] eo2 = new int[2]; for (int i = 0; i < m; i++) { eo2[p2[2][i] % 2]++; } int max = Math.max(eo2[0], eo2[1]); - int[][] p1 = parents(g1, 0); + int[][] p1 = parents(g1); int[] eo1 = new int[2]; for (int i = 0; i < n; i++) { eo1[p1[2][i] % 2]++; @@ -29,14 +29,14 @@ public int[] maxTargetNodes(int[][] edges1, int[][] edges2) { return ans; } - private int[][] parents(int[][] g, int root) { + private int[][] parents(int[][] g) { int n = g.length; int[] par = new int[n]; Arrays.fill(par, -1); int[] depth = new int[n]; depth[0] = 0; int[] q = new int[n]; - q[0] = root; + q[0] = 0; int p = 0; int r = 1; while (p < r) { From 35bce0f47a5bc569ef04d210760a8552db554e67 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 3 Dec 2024 03:10:57 +0200 Subject: [PATCH 12/16] Fixed sonar --- .../s3361_shift_distance_between_two_strings/Solution.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java b/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java index c32d2cfba..58fe5d81a 100644 --- a/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java +++ b/src/main/java/g3301_3400/s3361_shift_distance_between_two_strings/Solution.java @@ -8,12 +8,14 @@ public long shiftDistance(String s, String t, int[] nextCost, int[] previousCost long cost; for (int i = 0; i < 26; i++) { cost = nextCost[i]; - for (int j = (i == 25 ? 0 : i + 1); j != i; j++) { + int j = i == 25 ? 0 : i + 1; + while (j != i) { costs[i][j] = cost; cost += nextCost[j]; if (j == 25) { j = -1; } + j++; } } for (int i = 0; i < 26; i++) { From 05e4995fc7983bbcec01932140d66abca632deef Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 3 Dec 2024 03:20:13 +0200 Subject: [PATCH 13/16] Added test --- .../SolutionTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/SolutionTest.java b/src/test/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/SolutionTest.java index 8b882bc33..080967e43 100644 --- a/src/test/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/SolutionTest.java +++ b/src/test/java/g3301_3400/s3371_identify_the_largest_outlier_in_an_array/SolutionTest.java @@ -20,4 +20,9 @@ void getLargestOutlier2() { void getLargestOutlier3() { assertThat(new Solution().getLargestOutlier(new int[] {1, 1, 1, 1, 1, 5, 5}), equalTo(5)); } + + @Test + void getLargestOutlier4() { + assertThat(new Solution().getLargestOutlier(new int[] {-108, -108, -517}), equalTo(-517)); + } } From c286497fa0f2fb437a791c586306ca0ebc27615a Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 3 Dec 2024 03:23:31 +0200 Subject: [PATCH 14/16] Added test --- .../s3366_minimum_array_sum/SolutionTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/test/java/g3301_3400/s3366_minimum_array_sum/SolutionTest.java b/src/test/java/g3301_3400/s3366_minimum_array_sum/SolutionTest.java index aed497bf9..9314356d6 100644 --- a/src/test/java/g3301_3400/s3366_minimum_array_sum/SolutionTest.java +++ b/src/test/java/g3301_3400/s3366_minimum_array_sum/SolutionTest.java @@ -15,4 +15,18 @@ void minArraySum() { void minArraySum2() { assertThat(new Solution().minArraySum(new int[] {2, 4, 3}, 3, 2, 1), equalTo(3)); } + + @Test + void minArraySum3() { + assertThat( + new Solution() + .minArraySum( + new int[] { + 1, 3, 5, 7, 9, 12, 12, 12, 13, 15, 15, 15, 16, 17, 19, 20 + }, + 11, + 15, + 4), + equalTo(77)); + } } From 0e35ce3924d425213b6a5df13f47bb664240d3f2 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 3 Dec 2024 03:26:01 +0200 Subject: [PATCH 15/16] Added test --- .../SolutionTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/SolutionTest.java b/src/test/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/SolutionTest.java index 412a05941..df5b6cc57 100644 --- a/src/test/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/SolutionTest.java +++ b/src/test/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/SolutionTest.java @@ -31,4 +31,11 @@ void maximizeSumOfWeights2() { 3), equalTo(65L)); } + + @Test + void maximizeSumOfWeights3() { + assertThat( + new Solution().maximizeSumOfWeights(new int[][] {{0, 1, 34}, {0, 2, 17}}, 1), + equalTo(34L)); + } } From 8f1365214c0b447caef1fe729ee8a0e15c041029 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 3 Dec 2024 03:32:06 +0200 Subject: [PATCH 16/16] Improved tags --- .../Solution.java | 2 +- .../Solution.java | 2 +- .../Solution.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java b/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java index e7f21530b..a02e3c81a 100644 --- a/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java +++ b/src/main/java/g3301_3400/s3367_maximize_sum_of_weights_after_edge_removals/Solution.java @@ -1,6 +1,6 @@ package g3301_3400.s3367_maximize_sum_of_weights_after_edge_removals; -// #Hard #Dynamic_Programming #Tree #Depth_First_Search +// #Hard #Dynamic_Programming #Depth_First_Search #Tree // #2024_12_03_Time_104_ms_(91.49%)_Space_147.1_MB_(58.51%) import java.util.ArrayList; diff --git a/src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/Solution.java b/src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/Solution.java index f553f6a4e..fcd98f535 100644 --- a/src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/Solution.java +++ b/src/main/java/g3301_3400/s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i/Solution.java @@ -1,6 +1,6 @@ package g3301_3400.s3372_maximize_the_number_of_target_nodes_after_connecting_trees_i; -// #Medium #Tree #Depth_First_Search #Breadth_First_Search +// #Medium #Depth_First_Search #Breadth_First_Search #Tree // #2024_12_03_Time_50_ms_(99.49%)_Space_75.7_MB_(5.10%) import java.util.ArrayList; diff --git a/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java b/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java index 18ae7cccd..7b0b44623 100644 --- a/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java +++ b/src/main/java/g3301_3400/s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii/Solution.java @@ -1,6 +1,6 @@ package g3301_3400.s3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii; -// #Hard #Tree #Depth_First_Search #Breadth_First_Search +// #Hard #Depth_First_Search #Breadth_First_Search #Tree // #2024_12_03_Time_26_ms_(98.75%)_Space_114.7_MB_(80.00%) import java.util.Arrays;