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..3f6971927
--- /dev/null
+++ b/src/main/java/g3101_3200/s3200_maximum_height_of_a_triangle/Solution.java
@@ -0,0 +1,33 @@
+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%)
+
+@SuppressWarnings("java:S135")
+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:**
+
+
+
+The only possible arrangement is shown above.
+
+**Example 2:**
+
+**Input:** red = 2, blue = 1
+
+**Output:** 2
+
+**Explanation:**
+
+
+ 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:**
+
+
+ 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..89aeb6cc7
--- /dev/null
+++ b/src/main/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/Solution.java
@@ -0,0 +1,77 @@
+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];
+ 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:**
+
+**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:**
+
+
+
+**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));
+ }
+}