From c4dd90970881919b5bd9db5e9fc5b18dab9e0db2 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Thu, 4 Jul 2024 04:35:01 +0300 Subject: [PATCH 1/2] Added tasks 3200-3203 --- .../Solution.java | 32 ++++++++ .../readme.md | 53 ++++++++++++ .../Solution.java | 35 ++++++++ .../readme.md | 48 +++++++++++ .../Solution.java | 25 ++++++ .../readme.md | 37 +++++++++ .../Solution.java | 81 +++++++++++++++++++ .../readme.md | 45 +++++++++++ .../SolutionTest.java | 18 +++++ .../SolutionTest.java | 18 +++++ .../SolutionTest.java | 18 +++++ .../SolutionTest.java | 31 +++++++ 12 files changed, 441 insertions(+) create mode 100644 src/main/java/g3101_3200/s3200_maximum_height_of_a_triangle/Solution.java create mode 100644 src/main/java/g3101_3200/s3200_maximum_height_of_a_triangle/readme.md create mode 100644 src/main/java/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/Solution.java create mode 100644 src/main/java/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/readme.md create mode 100644 src/main/java/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/Solution.java create mode 100644 src/main/java/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/readme.md create mode 100644 src/main/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/Solution.java create mode 100644 src/main/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/readme.md create mode 100644 src/test/java/g3101_3200/s3200_maximum_height_of_a_triangle/SolutionTest.java create mode 100644 src/test/java/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/SolutionTest.java create mode 100644 src/test/java/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/SolutionTest.java create mode 100644 src/test/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/SolutionTest.java diff --git a/src/main/java/g3101_3200/s3200_maximum_height_of_a_triangle/Solution.java b/src/main/java/g3101_3200/s3200_maximum_height_of_a_triangle/Solution.java new file mode 100644 index 000000000..a66c094e6 --- /dev/null +++ b/src/main/java/g3101_3200/s3200_maximum_height_of_a_triangle/Solution.java @@ -0,0 +1,32 @@ +package g3101_3200.s3200_maximum_height_of_a_triangle; + +// #Easy #Array #Enumeration #2024_07_04_Time_1_ms_(86.34%)_Space_40.5_MB_(90.34%) + +public class Solution { + private int count(int v1, int v2) { + int ct = 1; + boolean flag = true; + while (true) { + if (flag) { + if (ct <= v1) { + v1 -= ct; + } else { + break; + } + } else { + if (ct <= v2) { + v2 -= ct; + } else { + break; + } + } + ct++; + flag = !flag; + } + return ct - 1; + } + + public int maxHeightOfTriangle(int red, int blue) { + return Math.max(count(red, blue), count(blue, red)); + } +} diff --git a/src/main/java/g3101_3200/s3200_maximum_height_of_a_triangle/readme.md b/src/main/java/g3101_3200/s3200_maximum_height_of_a_triangle/readme.md new file mode 100644 index 000000000..6f6de85a3 --- /dev/null +++ b/src/main/java/g3101_3200/s3200_maximum_height_of_a_triangle/readme.md @@ -0,0 +1,53 @@ +3200\. Maximum Height of a Triangle + +Easy + +You are given two integers `red` and `blue` representing the count of red and blue colored balls. You have to arrange these balls to form a triangle such that the 1st row will have 1 ball, the 2nd row will have 2 balls, the 3rd row will have 3 balls, and so on. + +All the balls in a particular row should be the **same** color, and adjacent rows should have **different** colors. + +Return the **maximum** _height of the triangle_ that can be achieved. + +**Example 1:** + +**Input:** red = 2, blue = 4 + +**Output:** 3 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2024/06/16/brb.png) + +The only possible arrangement is shown above. + +**Example 2:** + +**Input:** red = 2, blue = 1 + +**Output:** 2 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2024/06/16/br.png) + The only possible arrangement is shown above. + +**Example 3:** + +**Input:** red = 1, blue = 1 + +**Output:** 1 + +**Example 4:** + +**Input:** red = 10, blue = 1 + +**Output:** 2 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2024/06/16/br.png) + The only possible arrangement is shown above. + +**Constraints:** + +* `1 <= red, blue <= 100` \ No newline at end of file diff --git a/src/main/java/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/Solution.java b/src/main/java/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/Solution.java new file mode 100644 index 000000000..c57d851a1 --- /dev/null +++ b/src/main/java/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/Solution.java @@ -0,0 +1,35 @@ +package g3201_3300.s3201_find_the_maximum_length_of_valid_subsequence_i; + +// #Medium #Array #Dynamic_Programming #2024_07_04_Time_5_ms_(82.23%)_Space_61.7_MB_(91.46%) + +class Solution { + public int maximumLength(int[] nums) { + int n = nums.length; + int alter = 1; + int odd = 0; + int even = 0; + if (nums[0] % 2 == 0) { + even++; + } else { + odd++; + } + boolean lastodd = nums[0] % 2 != 0; + for (int i = 1; i < n; i++) { + boolean flag = nums[i] % 2 == 0; + if (flag) { + if (lastodd) { + alter++; + lastodd = false; + } + even++; + } else { + if (!lastodd) { + alter++; + lastodd = true; + } + odd++; + } + } + return Math.max(alter, Math.max(odd, even)); + } +} diff --git a/src/main/java/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/readme.md b/src/main/java/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/readme.md new file mode 100644 index 000000000..119c65799 --- /dev/null +++ b/src/main/java/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/readme.md @@ -0,0 +1,48 @@ +3201\. Find the Maximum Length of Valid Subsequence I + +Medium + +You are given an integer array `nums`. + +A subsequence `sub` of `nums` with length `x` is called **valid** if it satisfies: + +* `(sub[0] + sub[1]) % 2 == (sub[1] + sub[2]) % 2 == ... == (sub[x - 2] + sub[x - 1]) % 2.` + +Return the length of the **longest** **valid** subsequence of `nums`. + +A **subsequence** is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements. + +**Example 1:** + +**Input:** nums = [1,2,3,4] + +**Output:** 4 + +**Explanation:** + +The longest valid subsequence is `[1, 2, 3, 4]`. + +**Example 2:** + +**Input:** nums = [1,2,1,1,2,1,2] + +**Output:** 6 + +**Explanation:** + +The longest valid subsequence is `[1, 2, 1, 2, 1, 2]`. + +**Example 3:** + +**Input:** nums = [1,3] + +**Output:** 2 + +**Explanation:** + +The longest valid subsequence is `[1, 3]`. + +**Constraints:** + +* 2 <= nums.length <= 2 * 105 +* 1 <= nums[i] <= 107 \ No newline at end of file diff --git a/src/main/java/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/Solution.java b/src/main/java/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/Solution.java new file mode 100644 index 000000000..9e95a22c3 --- /dev/null +++ b/src/main/java/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/Solution.java @@ -0,0 +1,25 @@ +package g3201_3300.s3202_find_the_maximum_length_of_valid_subsequence_ii; + +// #Medium #Array #Dynamic_Programming #2024_07_04_Time_34_ms_(92.46%)_Space_51_MB_(45.95%) + +public class Solution { + public int maximumLength(int[] nums, int k) { + // dp array to store the index against each possible modulo + int[][] dp = new int[nums.length + 1][k + 1]; + int longest = 0; + for (int i = 0; i < nums.length; i++) { + for (int j = 0; j < i; j++) { + // Checking the modulo with each previous number + int val = (nums[i] + nums[j]) % k; + // storing the number of pairs that have the same modulo. + // it would be one more than the number of pairs with the same modulo at the last + // index + dp[i][val] = dp[j][val] + 1; + // Calculating the max seen till now + longest = Math.max(longest, dp[i][val]); + } + } + // total number of elements in the subsequence would be 1 more than the number of pairs + return longest + 1; + } +} diff --git a/src/main/java/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/readme.md b/src/main/java/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/readme.md new file mode 100644 index 000000000..5f79a06d4 --- /dev/null +++ b/src/main/java/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/readme.md @@ -0,0 +1,37 @@ +3202\. Find the Maximum Length of Valid Subsequence II + +Medium + +You are given an integer array `nums` and a **positive** integer `k`. + +A subsequence `sub` of `nums` with length `x` is called **valid** if it satisfies: + +* `(sub[0] + sub[1]) % k == (sub[1] + sub[2]) % k == ... == (sub[x - 2] + sub[x - 1]) % k.` + +Return the length of the **longest** **valid** subsequence of `nums`. + +**Example 1:** + +**Input:** nums = [1,2,3,4,5], k = 2 + +**Output:** 5 + +**Explanation:** + +The longest valid subsequence is `[1, 2, 3, 4, 5]`. + +**Example 2:** + +**Input:** nums = [1,4,2,3,1,4], k = 3 + +**Output:** 4 + +**Explanation:** + +The longest valid subsequence is `[1, 4, 1, 4]`. + +**Constraints:** + +* 2 <= nums.length <= 103 +* 1 <= nums[i] <= 107 +* 1 <= k <= 103 \ No newline at end of file diff --git a/src/main/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/Solution.java b/src/main/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/Solution.java new file mode 100644 index 000000000..bd4d1676c --- /dev/null +++ b/src/main/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/Solution.java @@ -0,0 +1,81 @@ +package g3201_3300.s3203_find_minimum_diameter_after_merging_two_trees; + +// #Hard #Tree #Graph #Depth_First_Search #Breadth_First_Search +// #2024_07_04_Time_29_ms_(99.83%)_Space_110.9_MB_(86.36%) + +import java.util.Arrays; + +public class Solution { + public int minimumDiameterAfterMerge(int[][] edges1, int[][] edges2) { + int n = edges1.length + 1; + int[][] g = packU(n, edges1); + int m = edges2.length + 1; + int[][] h = packU(m, edges2); + int[] d1 = diameter(g); + int[] d2 = diameter(h); + int ans = Math.max(d1[0], d2[0]); + ans = Math.max((d1[0] + 1) / 2 + (d2[0] + 1) / 2 + 1, ans); + return ans; + } + + public static int[] diameter(int[][] g) { + int n = g.length; + int f0; + int f1; + int d01; + int[] q = new int[n]; + boolean[] ved = new boolean[n]; + { + int qp = 0; + q[qp++] = 0; + ved[0] = true; + for (int i = 0; i < qp; i++) { + int cur = q[i]; + for (int e : g[cur]) { + if (!ved[e]) { + ved[e] = true; + q[qp++] = e; + } + } + } + f0 = q[n - 1]; + } + { + int[] d = new int[n]; + int qp = 0; + Arrays.fill(ved, false); + q[qp++] = f0; + ved[f0] = true; + for (int i = 0; i < qp; i++) { + int cur = q[i]; + for (int e : g[cur]) { + if (!ved[e]) { + ved[e] = true; + q[qp++] = e; + d[e] = d[cur] + 1; + } + } + } + f1 = q[n - 1]; + d01 = d[f1]; + } + return new int[] {d01, f0, f1}; + } + + public static 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 = 0; i < n; i++) { + g[i] = new int[p[i]]; + } + for (int[] u : ft) { + g[u[0]][--p[u[0]]] = u[1]; + g[u[1]][--p[u[1]]] = u[0]; + } + return g; + } +} diff --git a/src/main/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/readme.md b/src/main/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/readme.md new file mode 100644 index 000000000..27b313d83 --- /dev/null +++ b/src/main/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/readme.md @@ -0,0 +1,45 @@ +3203\. Find Minimum Diameter After Merging Two Trees + +Hard + +There exist two **undirected** trees with `n` and `m` nodes, numbered from `0` to `n - 1` and from `0` to `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 must connect one node from the first tree with another node from the second tree with an edge. + +Return the **minimum** possible **diameter** of the resulting tree. + +The **diameter** of a tree is the length of the _longest_ path between any two nodes in the tree. + +**Example 1:**![](https://assets.leetcode.com/uploads/2024/04/22/example11-transformed.png) + +**Input:** edges1 = [[0,1],[0,2],[0,3]], edges2 = [[0,1]] + +**Output:** 3 + +**Explanation:** + +We can obtain a tree of diameter 3 by connecting node 0 from the first tree with any node from the second tree. + +**Example 2:** + +![](https://assets.leetcode.com/uploads/2024/04/22/example211.png) + +**Input:** edges1 = [[0,1],[0,2],[0,3],[2,4],[2,5],[3,6],[2,7]], edges2 = [[0,1],[0,2],[0,3],[2,4],[2,5],[3,6],[2,7]] + +**Output:** 5 + +**Explanation:** + +We can obtain a tree of diameter 5 by connecting node 0 from the first tree with node 0 from the second tree. + +**Constraints:** + +* 1 <= 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/g3101_3200/s3200_maximum_height_of_a_triangle/SolutionTest.java b/src/test/java/g3101_3200/s3200_maximum_height_of_a_triangle/SolutionTest.java new file mode 100644 index 000000000..767ab26c9 --- /dev/null +++ b/src/test/java/g3101_3200/s3200_maximum_height_of_a_triangle/SolutionTest.java @@ -0,0 +1,18 @@ +package g3101_3200.s3200_maximum_height_of_a_triangle; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxHeightOfTriangle() { + assertThat(new Solution().maxHeightOfTriangle(2, 4), equalTo(3)); + } + + @Test + void maxHeightOfTriangle2() { + assertThat(new Solution().maxHeightOfTriangle(2, 1), equalTo(2)); + } +} diff --git a/src/test/java/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/SolutionTest.java b/src/test/java/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/SolutionTest.java new file mode 100644 index 000000000..39d110d99 --- /dev/null +++ b/src/test/java/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/SolutionTest.java @@ -0,0 +1,18 @@ +package g3201_3300.s3201_find_the_maximum_length_of_valid_subsequence_i; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maximumLength() { + assertThat(new Solution().maximumLength(new int[] {1, 2, 3, 4}), equalTo(4)); + } + + @Test + void maximumLength2() { + assertThat(new Solution().maximumLength(new int[] {1, 2, 1, 1, 2, 1, 2}), equalTo(6)); + } +} diff --git a/src/test/java/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/SolutionTest.java b/src/test/java/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/SolutionTest.java new file mode 100644 index 000000000..72e470891 --- /dev/null +++ b/src/test/java/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/SolutionTest.java @@ -0,0 +1,18 @@ +package g3201_3300.s3202_find_the_maximum_length_of_valid_subsequence_ii; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maximumLength() { + assertThat(new Solution().maximumLength(new int[] {1, 2, 3, 4, 5}, 2), equalTo(5)); + } + + @Test + void maximumLength2() { + assertThat(new Solution().maximumLength(new int[] {1, 4, 2, 3, 1, 4}, 3), equalTo(4)); + } +} diff --git a/src/test/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/SolutionTest.java b/src/test/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/SolutionTest.java new file mode 100644 index 000000000..3062bfd68 --- /dev/null +++ b/src/test/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/SolutionTest.java @@ -0,0 +1,31 @@ +package g3201_3300.s3203_find_minimum_diameter_after_merging_two_trees; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void minimumDiameterAfterMerge() { + assertThat( + new Solution() + .minimumDiameterAfterMerge( + new int[][] {{0, 1}, {0, 2}, {0, 3}}, new int[][] {{0, 1}}), + equalTo(3)); + } + + @Test + void minimumDiameterAfterMerge2() { + assertThat( + new Solution() + .minimumDiameterAfterMerge( + new int[][] { + {0, 1}, {0, 2}, {0, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7} + }, + new int[][] { + {0, 1}, {0, 2}, {0, 3}, {2, 4}, {2, 5}, {3, 6}, {2, 7} + }), + equalTo(5)); + } +} From 56d123bbfc7b1b5170ff284a4f249136fb5e7133 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Thu, 4 Jul 2024 04:42:07 +0300 Subject: [PATCH 2/2] Fixed sonar --- .../Solution.java | 1 + .../Solution.java | 52 +++++++++---------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/main/java/g3101_3200/s3200_maximum_height_of_a_triangle/Solution.java b/src/main/java/g3101_3200/s3200_maximum_height_of_a_triangle/Solution.java index a66c094e6..3f6971927 100644 --- a/src/main/java/g3101_3200/s3200_maximum_height_of_a_triangle/Solution.java +++ b/src/main/java/g3101_3200/s3200_maximum_height_of_a_triangle/Solution.java @@ -2,6 +2,7 @@ // #Easy #Array #Enumeration #2024_07_04_Time_1_ms_(86.34%)_Space_40.5_MB_(90.34%) +@SuppressWarnings("java:S135") public class Solution { private int count(int v1, int v2) { int ct = 1; diff --git a/src/main/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/Solution.java b/src/main/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/Solution.java index bd4d1676c..89aeb6cc7 100644 --- a/src/main/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/Solution.java +++ b/src/main/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/Solution.java @@ -25,40 +25,36 @@ public static int[] diameter(int[][] g) { int d01; int[] q = new int[n]; boolean[] ved = new boolean[n]; - { - int qp = 0; - q[qp++] = 0; - ved[0] = true; - for (int i = 0; i < qp; i++) { - int cur = q[i]; - for (int e : g[cur]) { - if (!ved[e]) { - ved[e] = true; - q[qp++] = e; - } + int qp = 0; + q[qp++] = 0; + ved[0] = true; + for (int i = 0; i < qp; i++) { + int cur = q[i]; + for (int e : g[cur]) { + if (!ved[e]) { + ved[e] = true; + q[qp++] = e; } } - f0 = q[n - 1]; } - { - int[] d = new int[n]; - int qp = 0; - Arrays.fill(ved, false); - q[qp++] = f0; - ved[f0] = true; - for (int i = 0; i < qp; i++) { - int cur = q[i]; - for (int e : g[cur]) { - if (!ved[e]) { - ved[e] = true; - q[qp++] = e; - d[e] = d[cur] + 1; - } + f0 = q[n - 1]; + int[] d = new int[n]; + qp = 0; + Arrays.fill(ved, false); + q[qp++] = f0; + ved[f0] = true; + for (int i = 0; i < qp; i++) { + int cur = q[i]; + for (int e : g[cur]) { + if (!ved[e]) { + ved[e] = true; + q[qp++] = e; + d[e] = d[cur] + 1; } } - f1 = q[n - 1]; - d01 = d[f1]; } + f1 = q[n - 1]; + d01 = d[f1]; return new int[] {d01, f0, f1}; }