diff --git a/src/main/kotlin/g3101_3200/s3200_maximum_height_of_a_triangle/Solution.kt b/src/main/kotlin/g3101_3200/s3200_maximum_height_of_a_triangle/Solution.kt new file mode 100644 index 000000000..5af8bb340 --- /dev/null +++ b/src/main/kotlin/g3101_3200/s3200_maximum_height_of_a_triangle/Solution.kt @@ -0,0 +1,37 @@ +package g3101_3200.s3200_maximum_height_of_a_triangle + +// #Easy #Array #Enumeration #2024_07_06_Time_136_ms_(81.36%)_Space_33.8_MB_(28.81%) + +import kotlin.math.max + +@Suppress("NAME_SHADOWING") +class Solution { + private fun count(v1: Int, v2: Int): Int { + var v1 = v1 + var v2 = v2 + var ct = 1 + var 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 + } + + fun maxHeightOfTriangle(red: Int, blue: Int): Int { + return max(count(red, blue), count(blue, red)) + } +} diff --git a/src/main/kotlin/g3101_3200/s3200_maximum_height_of_a_triangle/readme.md b/src/main/kotlin/g3101_3200/s3200_maximum_height_of_a_triangle/readme.md new file mode 100644 index 000000000..6f6de85a3 --- /dev/null +++ b/src/main/kotlin/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/kotlin/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/Solution.kt b/src/main/kotlin/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/Solution.kt new file mode 100644 index 000000000..ad083da42 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/Solution.kt @@ -0,0 +1,37 @@ +package g3201_3300.s3201_find_the_maximum_length_of_valid_subsequence_i + +// #Medium #Array #Dynamic_Programming #2024_07_06_Time_512_ms_(89.36%)_Space_62.1_MB_(76.60%) + +import kotlin.math.max + +class Solution { + fun maximumLength(nums: IntArray): Int { + val n = nums.size + var alter = 1 + var odd = 0 + var even = 0 + if (nums[0] % 2 == 0) { + even++ + } else { + odd++ + } + var lastodd = nums[0] % 2 != 0 + for (i in 1 until n) { + val flag = nums[i] % 2 == 0 + if (flag) { + if (lastodd) { + alter++ + lastodd = false + } + even++ + } else { + if (!lastodd) { + alter++ + lastodd = true + } + odd++ + } + } + return max(alter, max(odd, even)) + } +} diff --git a/src/main/kotlin/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/readme.md b/src/main/kotlin/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/kotlin/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/kotlin/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/Solution.kt b/src/main/kotlin/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/Solution.kt new file mode 100644 index 000000000..0fe1affbd --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/Solution.kt @@ -0,0 +1,27 @@ +package g3201_3300.s3202_find_the_maximum_length_of_valid_subsequence_ii + +// #Medium #Array #Dynamic_Programming #2024_07_06_Time_255_ms_(97.30%)_Space_49_MB_(78.38%) + +import kotlin.math.max + +class Solution { + fun maximumLength(nums: IntArray, k: Int): Int { + // dp array to store the index against each possible modulo + val dp = Array(nums.size + 1) { IntArray(k + 1) } + var longest = 0 + for (i in nums.indices) { + for (j in 0 until i) { + // Checking the modulo with each previous number + val `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 = 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/kotlin/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/readme.md b/src/main/kotlin/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/kotlin/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/kotlin/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/Solution.kt b/src/main/kotlin/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/Solution.kt new file mode 100644 index 000000000..445a08a34 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/Solution.kt @@ -0,0 +1,86 @@ +package g3201_3300.s3203_find_minimum_diameter_after_merging_two_trees + +// #Hard #Depth_First_Search #Breadth_First_Search #Tree #Graph +// #2024_07_06_Time_1156_ms_(100.00%)_Space_119.4_MB_(80.00%) + +import kotlin.math.max + +class Solution { + fun minimumDiameterAfterMerge(edges1: Array, edges2: Array): Int { + val n = edges1.size + 1 + val g = packU(n, edges1) + val m = edges2.size + 1 + val h = packU(m, edges2) + val d1 = diameter(g) + val d2 = diameter(h) + var ans = max(d1[0], d2[0]) + ans = max( + ((d1[0] + 1) / 2 + ((d2[0] + 1) / 2) + 1), + ans + ) + return ans + } + + private fun diameter(g: Array): IntArray { + val n = g.size + val f0: Int + val f1: Int + val d01: Int + val q = IntArray(n) + val ved = BooleanArray(n) + var qp = 0 + q[qp++] = 0 + ved[0] = true + run { + var i = 0 + while (i < qp) { + val cur = q[i] + for (e in g[cur]!!) { + if (!ved[e]) { + ved[e] = true + q[qp++] = e + } + } + i++ + } + } + f0 = q[n - 1] + val d = IntArray(n) + qp = 0 + ved.fill(false) + q[qp++] = f0 + ved[f0] = true + var i = 0 + while (i < qp) { + val cur = q[i] + for (e in g[cur]!!) { + if (!ved[e]) { + ved[e] = true + q[qp++] = e + d[e] = d[cur] + 1 + } + } + i++ + } + f1 = q[n - 1] + d01 = d[f1] + return intArrayOf(d01, f0, f1) + } + + private fun packU(n: Int, ft: Array): Array { + val g = arrayOfNulls(n) + val p = IntArray(n) + for (u in ft) { + p[u[0]]++ + p[u[1]]++ + } + for (i in 0 until n) { + g[i] = IntArray(p[i]) + } + for (u in ft) { + g[u[0]]!![--p[u[0]]] = u[1] + g[u[1]]!![--p[u[1]]] = u[0] + } + return g + } +} diff --git a/src/main/kotlin/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/readme.md b/src/main/kotlin/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/readme.md new file mode 100644 index 000000000..27b313d83 --- /dev/null +++ b/src/main/kotlin/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/kotlin/g3101_3200/s3200_maximum_height_of_a_triangle/SolutionTest.kt b/src/test/kotlin/g3101_3200/s3200_maximum_height_of_a_triangle/SolutionTest.kt new file mode 100644 index 000000000..281467794 --- /dev/null +++ b/src/test/kotlin/g3101_3200/s3200_maximum_height_of_a_triangle/SolutionTest.kt @@ -0,0 +1,17 @@ +package g3101_3200.s3200_maximum_height_of_a_triangle + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun maxHeightOfTriangle() { + assertThat(Solution().maxHeightOfTriangle(2, 4), equalTo(3)) + } + + @Test + fun maxHeightOfTriangle2() { + assertThat(Solution().maxHeightOfTriangle(2, 1), equalTo(2)) + } +} diff --git a/src/test/kotlin/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/SolutionTest.kt new file mode 100644 index 000000000..ea855e12d --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3201_find_the_maximum_length_of_valid_subsequence_i/SolutionTest.kt @@ -0,0 +1,17 @@ +package g3201_3300.s3201_find_the_maximum_length_of_valid_subsequence_i + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun maximumLength() { + assertThat(Solution().maximumLength(intArrayOf(1, 2, 3, 4)), equalTo(4)) + } + + @Test + fun maximumLength2() { + assertThat(Solution().maximumLength(intArrayOf(1, 2, 1, 1, 2, 1, 2)), equalTo(6)) + } +} diff --git a/src/test/kotlin/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/SolutionTest.kt new file mode 100644 index 000000000..81d8c1dd3 --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3202_find_the_maximum_length_of_valid_subsequence_ii/SolutionTest.kt @@ -0,0 +1,17 @@ +package g3201_3300.s3202_find_the_maximum_length_of_valid_subsequence_ii + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun maximumLength() { + assertThat(Solution().maximumLength(intArrayOf(1, 2, 3, 4, 5), 2), equalTo(5)) + } + + @Test + fun maximumLength2() { + assertThat(Solution().maximumLength(intArrayOf(1, 4, 2, 3, 1, 4), 3), equalTo(4)) + } +} diff --git a/src/test/kotlin/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/SolutionTest.kt new file mode 100644 index 000000000..509563fe2 --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/SolutionTest.kt @@ -0,0 +1,46 @@ +package g3201_3300.s3203_find_minimum_diameter_after_merging_two_trees + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun minimumDiameterAfterMerge() { + assertThat( + Solution() + .minimumDiameterAfterMerge( + arrayOf(intArrayOf(0, 1), intArrayOf(0, 2), intArrayOf(0, 3)), arrayOf(intArrayOf(0, 1)) + ), + equalTo(3) + ) + } + + @Test + fun minimumDiameterAfterMerge2() { + assertThat( + Solution() + .minimumDiameterAfterMerge( + arrayOf( + intArrayOf(0, 1), + intArrayOf(0, 2), + intArrayOf(0, 3), + intArrayOf(2, 4), + intArrayOf(2, 5), + intArrayOf(3, 6), + intArrayOf(2, 7) + ), + arrayOf( + intArrayOf(0, 1), + intArrayOf(0, 2), + intArrayOf(0, 3), + intArrayOf(2, 4), + intArrayOf(2, 5), + intArrayOf(3, 6), + intArrayOf(2, 7) + ) + ), + equalTo(5) + ) + } +}