diff --git a/src/main/java/g3001_3100/s3090_maximum_length_substring_with_two_occurrences/Solution.java b/src/main/java/g3001_3100/s3090_maximum_length_substring_with_two_occurrences/Solution.java
new file mode 100644
index 000000000..3889f23c6
--- /dev/null
+++ b/src/main/java/g3001_3100/s3090_maximum_length_substring_with_two_occurrences/Solution.java
@@ -0,0 +1,22 @@
+package g3001_3100.s3090_maximum_length_substring_with_two_occurrences;
+
+// #Easy #String #Hash_Table #Sliding_Window #2024_04_18_Time_1_ms_(100.00%)_Space_42.5_MB_(55.33%)
+
+public class Solution {
+ public int maximumLengthSubstring(String s) {
+ int[] freq = new int[26];
+ char[] chars = s.toCharArray();
+ int i = 0;
+ int len = s.length();
+ int max = 0;
+ for (int j = 0; j < len; j++) {
+ ++freq[chars[j] - 'a'];
+ while (freq[chars[j] - 'a'] == 3) {
+ --freq[chars[i] - 'a'];
+ i++;
+ }
+ max = Math.max(max, j - i + 1);
+ }
+ return max;
+ }
+}
diff --git a/src/main/java/g3001_3100/s3090_maximum_length_substring_with_two_occurrences/readme.md b/src/main/java/g3001_3100/s3090_maximum_length_substring_with_two_occurrences/readme.md
new file mode 100644
index 000000000..3b38da787
--- /dev/null
+++ b/src/main/java/g3001_3100/s3090_maximum_length_substring_with_two_occurrences/readme.md
@@ -0,0 +1,30 @@
+3090\. Maximum Length Substring With Two Occurrences
+
+Easy
+
+Given a string `s`, return the **maximum** length of a substring such that it contains _at most two occurrences_ of each character.
+
+**Example 1:**
+
+**Input:** s = "bcbbbcba"
+
+**Output:** 4
+
+**Explanation:**
+
+The following substring has a length of 4 and contains at most two occurrences of each character: "bcbbbcba"
.
+
+**Example 2:**
+
+**Input:** s = "aaaa"
+
+**Output:** 2
+
+**Explanation:**
+
+The following substring has a length of 2 and contains at most two occurrences of each character: "aaaa"
.
+
+**Constraints:**
+
+* `2 <= s.length <= 100`
+* `s` consists only of lowercase English letters.
\ No newline at end of file
diff --git a/src/main/java/g3001_3100/s3091_apply_operations_to_make_sum_of_array_greater_than_or_equal_to_k/Solution.java b/src/main/java/g3001_3100/s3091_apply_operations_to_make_sum_of_array_greater_than_or_equal_to_k/Solution.java
new file mode 100644
index 000000000..17a4949f3
--- /dev/null
+++ b/src/main/java/g3001_3100/s3091_apply_operations_to_make_sum_of_array_greater_than_or_equal_to_k/Solution.java
@@ -0,0 +1,10 @@
+package g3001_3100.s3091_apply_operations_to_make_sum_of_array_greater_than_or_equal_to_k;
+
+// #Medium #Math #Greedy #Enumeration #2024_04_18_Time_0_ms_(100.00%)_Space_40.6_MB_(62.55%)
+
+public class Solution {
+ public int minOperations(int k) {
+ int a = (int) Math.sqrt(k);
+ return a + (k - 1) / a - 1;
+ }
+}
diff --git a/src/main/java/g3001_3100/s3091_apply_operations_to_make_sum_of_array_greater_than_or_equal_to_k/readme.md b/src/main/java/g3001_3100/s3091_apply_operations_to_make_sum_of_array_greater_than_or_equal_to_k/readme.md
new file mode 100644
index 000000000..8df43c7ca
--- /dev/null
+++ b/src/main/java/g3001_3100/s3091_apply_operations_to_make_sum_of_array_greater_than_or_equal_to_k/readme.md
@@ -0,0 +1,42 @@
+3091\. Apply Operations to Make Sum of Array Greater Than or Equal to k
+
+Medium
+
+You are given a **positive** integer `k`. Initially, you have an array `nums = [1]`.
+
+You can perform **any** of the following operations on the array **any** number of times (**possibly zero**):
+
+* Choose any element in the array and **increase** its value by `1`.
+* Duplicate any element in the array and add it to the end of the array.
+
+Return _the **minimum** number of operations required to make the **sum** of elements of the final array greater than or equal to_ `k`.
+
+**Example 1:**
+
+**Input:** k = 11
+
+**Output:** 5
+
+**Explanation:**
+
+We can do the following operations on the array `nums = [1]`:
+
+* Increase the element by `1` three times. The resulting array is `nums = [4]`.
+* Duplicate the element two times. The resulting array is `nums = [4,4,4]`.
+
+The sum of the final array is `4 + 4 + 4 = 12` which is greater than or equal to `k = 11`.
+The total number of operations performed is `3 + 2 = 5`.
+
+**Example 2:**
+
+**Input:** k = 1
+
+**Output:** 0
+
+**Explanation:**
+
+The sum of the original array is already greater than or equal to `1`, so no operations are needed.
+
+**Constraints:**
+
+* 1 <= k <= 105
\ No newline at end of file
diff --git a/src/main/java/g3001_3100/s3092_most_frequent_ids/Solution.java b/src/main/java/g3001_3100/s3092_most_frequent_ids/Solution.java
new file mode 100644
index 000000000..a875bebdf
--- /dev/null
+++ b/src/main/java/g3001_3100/s3092_most_frequent_ids/Solution.java
@@ -0,0 +1,39 @@
+package g3001_3100.s3092_most_frequent_ids;
+
+// #Medium #Array #Hash_Table #Heap_Priority_Queue #Ordered_Set
+// #2024_04_18_Time_3_ms_(100.00%)_Space_69_MB_(49.39%)
+
+public class Solution {
+ public long[] mostFrequentIDs(int[] nums, int[] freq) {
+ int max = Integer.MIN_VALUE;
+ int n = nums.length;
+ for (int num : nums) {
+ max = Math.max(max, num);
+ }
+ long[] bins = new long[max + 1];
+ int mostFrequentID = 0;
+ long maxCount = 0;
+ long[] ans = new long[n];
+ for (int i = 0; i < n; i++) {
+ bins[nums[i]] += freq[i];
+ if (freq[i] > 0) {
+ if (bins[nums[i]] > maxCount) {
+ maxCount = bins[nums[i]];
+ mostFrequentID = nums[i];
+ }
+ } else {
+ if (nums[i] == mostFrequentID) {
+ maxCount = bins[nums[i]];
+ for (int j = 0; j <= max; j++) {
+ if (bins[j] > maxCount) {
+ maxCount = bins[j];
+ mostFrequentID = j;
+ }
+ }
+ }
+ }
+ ans[i] = maxCount;
+ }
+ return ans;
+ }
+}
diff --git a/src/main/java/g3001_3100/s3092_most_frequent_ids/readme.md b/src/main/java/g3001_3100/s3092_most_frequent_ids/readme.md
new file mode 100644
index 000000000..2dbfdc08b
--- /dev/null
+++ b/src/main/java/g3001_3100/s3092_most_frequent_ids/readme.md
@@ -0,0 +1,43 @@
+3092\. Most Frequent IDs
+
+Medium
+
+The problem involves tracking the frequency of IDs in a collection that changes over time. You have two integer arrays, `nums` and `freq`, of equal length `n`. Each element in `nums` represents an ID, and the corresponding element in `freq` indicates how many times that ID should be added to or removed from the collection at each step.
+
+* **Addition of IDs:** If `freq[i]` is positive, it means `freq[i]` IDs with the value `nums[i]` are added to the collection at step `i`.
+* **Removal of IDs:** If `freq[i]` is negative, it means `-freq[i]` IDs with the value `nums[i]` are removed from the collection at step `i`.
+
+Return an array `ans` of length `n`, where `ans[i]` represents the **count** of the _most frequent ID_ in the collection after the ith
step. If the collection is empty at any step, `ans[i]` should be 0 for that step.
+
+**Example 1:**
+
+**Input:** nums = [2,3,2,1], freq = [3,2,-3,1]
+
+**Output:** [3,3,2,2]
+
+**Explanation:**
+
+After step 0, we have 3 IDs with the value of 2. So `ans[0] = 3`.
+After step 1, we have 3 IDs with the value of 2 and 2 IDs with the value of 3. So `ans[1] = 3`.
+After step 2, we have 2 IDs with the value of 3. So `ans[2] = 2`.
+After step 3, we have 2 IDs with the value of 3 and 1 ID with the value of 1. So `ans[3] = 2`.
+
+**Example 2:**
+
+**Input:** nums = [5,5,3], freq = [2,-2,1]
+
+**Output:** [2,0,1]
+
+**Explanation:**
+
+After step 0, we have 2 IDs with the value of 5. So `ans[0] = 2`.
+After step 1, there are no IDs. So `ans[1] = 0`.
+After step 2, we have 1 ID with the value of 3. So `ans[2] = 1`.
+
+**Constraints:**
+
+* 1 <= nums.length == freq.length <= 105
+* 1 <= nums[i] <= 105
+* -105 <= freq[i] <= 105
+* `freq[i] != 0`
+* The input is generated such that the occurrences of an ID will not be negative in any step.
\ No newline at end of file
diff --git a/src/main/java/g3001_3100/s3093_longest_common_suffix_queries/Solution.java b/src/main/java/g3001_3100/s3093_longest_common_suffix_queries/Solution.java
new file mode 100644
index 000000000..4973a3354
--- /dev/null
+++ b/src/main/java/g3001_3100/s3093_longest_common_suffix_queries/Solution.java
@@ -0,0 +1,72 @@
+package g3001_3100.s3093_longest_common_suffix_queries;
+
+// #Hard #Array #String #Trie #2024_04_18_Time_39_ms_(93.67%)_Space_160.9_MB_(66.40%)
+
+public class Solution {
+ public int[] stringIndices(String[] wc, String[] wq) {
+ int minLength = wc[0].length();
+ int minIndex = 0;
+ int n = wc.length;
+ int m = wq.length;
+ for (int i = 0; i < n; i++) {
+ if (minLength > wc[i].length()) {
+ minLength = wc[i].length();
+ minIndex = i;
+ }
+ }
+ Trie root = new Trie(minIndex);
+ for (int i = 0; i < n; i++) {
+ Trie curr = root;
+ for (int j = wc[i].length() - 1; j >= 0; j--) {
+ char ch = wc[i].charAt(j);
+ if (curr.has(ch)) {
+ Trie next = curr.get(ch);
+ if (wc[next.index].length() > wc[i].length()) {
+ next.index = i;
+ }
+ curr = next;
+ } else {
+ curr.put(ch, i);
+ curr = curr.get(ch);
+ }
+ }
+ }
+ int[] ans = new int[m];
+ for (int i = 0; i < m; i++) {
+ Trie curr = root;
+ for (int j = wq[i].length() - 1; j >= 0; j--) {
+ char ch = wq[i].charAt(j);
+ if (curr.has(ch)) {
+ curr = curr.get(ch);
+ } else {
+ break;
+ }
+ }
+ ans[i] = curr.index;
+ }
+
+ return ans;
+ }
+
+ private static class Trie {
+ Trie[] ch;
+ int index;
+
+ Trie(int index) {
+ this.ch = new Trie[26];
+ this.index = index;
+ }
+
+ Trie get(char ch) {
+ return this.ch[ch - 'a'];
+ }
+
+ boolean has(char ch) {
+ return this.ch[ch - 'a'] != null;
+ }
+
+ void put(char ch, int index) {
+ this.ch[ch - 'a'] = new Trie(index);
+ }
+ }
+}
diff --git a/src/main/java/g3001_3100/s3093_longest_common_suffix_queries/readme.md b/src/main/java/g3001_3100/s3093_longest_common_suffix_queries/readme.md
new file mode 100644
index 000000000..f0aa2c2e2
--- /dev/null
+++ b/src/main/java/g3001_3100/s3093_longest_common_suffix_queries/readme.md
@@ -0,0 +1,47 @@
+3093\. Longest Common Suffix Queries
+
+Hard
+
+You are given two arrays of strings `wordsContainer` and `wordsQuery`.
+
+For each `wordsQuery[i]`, you need to find a string from `wordsContainer` that has the **longest common suffix** with `wordsQuery[i]`. If there are two or more strings in `wordsContainer` that share the longest common suffix, find the string that is the **smallest** in length. If there are two or more such strings that have the **same** smallest length, find the one that occurred **earlier** in `wordsContainer`.
+
+Return _an array of integers_ `ans`_, where_ `ans[i]` _is the index of the string in_ `wordsContainer` _that has the **longest common suffix** with_ `wordsQuery[i]`_._
+
+**Example 1:**
+
+**Input:** wordsContainer = ["abcd","bcd","xbcd"], wordsQuery = ["cd","bcd","xyz"]
+
+**Output:** [1,1,1]
+
+**Explanation:**
+
+Let's look at each `wordsQuery[i]` separately:
+
+* For `wordsQuery[0] = "cd"`, strings from `wordsContainer` that share the longest common suffix `"cd"` are at indices 0, 1, and 2. Among these, the answer is the string at index 1 because it has the shortest length of 3.
+* For `wordsQuery[1] = "bcd"`, strings from `wordsContainer` that share the longest common suffix `"bcd"` are at indices 0, 1, and 2. Among these, the answer is the string at index 1 because it has the shortest length of 3.
+* For `wordsQuery[2] = "xyz"`, there is no string from `wordsContainer` that shares a common suffix. Hence the longest common suffix is `""`, that is shared with strings at index 0, 1, and 2. Among these, the answer is the string at index 1 because it has the shortest length of 3.
+
+**Example 2:**
+
+**Input:** wordsContainer = ["abcdefgh","poiuygh","ghghgh"], wordsQuery = ["gh","acbfgh","acbfegh"]
+
+**Output:** [2,0,2]
+
+**Explanation:**
+
+Let's look at each `wordsQuery[i]` separately:
+
+* For `wordsQuery[0] = "gh"`, strings from `wordsContainer` that share the longest common suffix `"gh"` are at indices 0, 1, and 2. Among these, the answer is the string at index 2 because it has the shortest length of 6.
+* For `wordsQuery[1] = "acbfgh"`, only the string at index 0 shares the longest common suffix `"fgh"`. Hence it is the answer, even though the string at index 2 is shorter.
+* For `wordsQuery[2] = "acbfegh"`, strings from `wordsContainer` that share the longest common suffix `"gh"` are at indices 0, 1, and 2. Among these, the answer is the string at index 2 because it has the shortest length of 6.
+
+**Constraints:**
+
+* 1 <= wordsContainer.length, wordsQuery.length <= 104
+* 1 <= wordsContainer[i].length <= 5 * 103
+* 1 <= wordsQuery[i].length <= 5 * 103
+* `wordsContainer[i]` consists only of lowercase English letters.
+* `wordsQuery[i]` consists only of lowercase English letters.
+* Sum of `wordsContainer[i].length` is at most 5 * 105
.
+* Sum of `wordsQuery[i].length` is at most 5 * 105
.
\ No newline at end of file
diff --git a/src/main/java/g3001_3100/s3095_shortest_subarray_with_or_at_least_k_i/Solution.java b/src/main/java/g3001_3100/s3095_shortest_subarray_with_or_at_least_k_i/Solution.java
new file mode 100644
index 000000000..fd66e79fb
--- /dev/null
+++ b/src/main/java/g3001_3100/s3095_shortest_subarray_with_or_at_least_k_i/Solution.java
@@ -0,0 +1,22 @@
+package g3001_3100.s3095_shortest_subarray_with_or_at_least_k_i;
+
+// #Easy #Array #Bit_Manipulation #Sliding_Window
+// #2024_04_18_Time_1_ms_(98.94%)_Space_42.3_MB_(57.80%)
+
+public class Solution {
+ public int minimumSubarrayLength(int[] nums, int k) {
+ int n = nums.length;
+ int maxL = n + 1;
+ int val;
+ for (int i = 0; i < n; i++) {
+ val = 0;
+ for (int j = i; j < n; j++) {
+ val |= nums[j];
+ if (val >= k) {
+ maxL = Math.min(maxL, j - i + 1);
+ }
+ }
+ }
+ return (maxL == n + 1) ? -1 : maxL;
+ }
+}
diff --git a/src/main/java/g3001_3100/s3095_shortest_subarray_with_or_at_least_k_i/readme.md b/src/main/java/g3001_3100/s3095_shortest_subarray_with_or_at_least_k_i/readme.md
new file mode 100644
index 000000000..0ac9a855d
--- /dev/null
+++ b/src/main/java/g3001_3100/s3095_shortest_subarray_with_or_at_least_k_i/readme.md
@@ -0,0 +1,45 @@
+3095\. Shortest Subarray With OR at Least K I
+
+Easy
+
+You are given an array `nums` of **non-negative** integers and an integer `k`.
+
+An array is called **special** if the bitwise `OR` of all of its elements is **at least** `k`.
+
+Return _the length of the **shortest** **special** **non-empty** subarray of_ `nums`, _or return_ `-1` _if no special subarray exists_.
+
+**Example 1:**
+
+**Input:** nums = [1,2,3], k = 2
+
+**Output:** 1
+
+**Explanation:**
+
+The subarray `[3]` has `OR` value of `3`. Hence, we return `1`.
+
+**Example 2:**
+
+**Input:** nums = [2,1,8], k = 10
+
+**Output:** 3
+
+**Explanation:**
+
+The subarray `[2,1,8]` has `OR` value of `11`. Hence, we return `3`.
+
+**Example 3:**
+
+**Input:** nums = [1,2], k = 0
+
+**Output:** 1
+
+**Explanation:**
+
+The subarray `[1]` has `OR` value of `1`. Hence, we return `1`.
+
+**Constraints:**
+
+* `1 <= nums.length <= 50`
+* `0 <= nums[i] <= 50`
+* `0 <= k < 64`
\ No newline at end of file
diff --git a/src/test/java/g3001_3100/s3090_maximum_length_substring_with_two_occurrences/SolutionTest.java b/src/test/java/g3001_3100/s3090_maximum_length_substring_with_two_occurrences/SolutionTest.java
new file mode 100644
index 000000000..18a2b9b79
--- /dev/null
+++ b/src/test/java/g3001_3100/s3090_maximum_length_substring_with_two_occurrences/SolutionTest.java
@@ -0,0 +1,18 @@
+package g3001_3100.s3090_maximum_length_substring_with_two_occurrences;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void maximumLengthSubstring() {
+ assertThat(new Solution().maximumLengthSubstring("bcbbbcba"), equalTo(4));
+ }
+
+ @Test
+ void maximumLengthSubstring2() {
+ assertThat(new Solution().maximumLengthSubstring("aaaa"), equalTo(2));
+ }
+}
diff --git a/src/test/java/g3001_3100/s3091_apply_operations_to_make_sum_of_array_greater_than_or_equal_to_k/SolutionTest.java b/src/test/java/g3001_3100/s3091_apply_operations_to_make_sum_of_array_greater_than_or_equal_to_k/SolutionTest.java
new file mode 100644
index 000000000..4c483baac
--- /dev/null
+++ b/src/test/java/g3001_3100/s3091_apply_operations_to_make_sum_of_array_greater_than_or_equal_to_k/SolutionTest.java
@@ -0,0 +1,18 @@
+package g3001_3100.s3091_apply_operations_to_make_sum_of_array_greater_than_or_equal_to_k;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void minOperations() {
+ assertThat(new Solution().minOperations(11), equalTo(5));
+ }
+
+ @Test
+ void minOperations2() {
+ assertThat(new Solution().minOperations(1), equalTo(0));
+ }
+}
diff --git a/src/test/java/g3001_3100/s3092_most_frequent_ids/SolutionTest.java b/src/test/java/g3001_3100/s3092_most_frequent_ids/SolutionTest.java
new file mode 100644
index 000000000..1a3feec5a
--- /dev/null
+++ b/src/test/java/g3001_3100/s3092_most_frequent_ids/SolutionTest.java
@@ -0,0 +1,22 @@
+package g3001_3100.s3092_most_frequent_ids;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void mostFrequentIDs() {
+ assertThat(
+ new Solution().mostFrequentIDs(new int[] {2, 3, 2, 1}, new int[] {3, 2, -3, 1}),
+ equalTo(new long[] {3, 3, 2, 2}));
+ }
+
+ @Test
+ void mostFrequentIDs2() {
+ assertThat(
+ new Solution().mostFrequentIDs(new int[] {5, 5, 3}, new int[] {2, -2, 1}),
+ equalTo(new long[] {2, 0, 1}));
+ }
+}
diff --git a/src/test/java/g3001_3100/s3093_longest_common_suffix_queries/SolutionTest.java b/src/test/java/g3001_3100/s3093_longest_common_suffix_queries/SolutionTest.java
new file mode 100644
index 000000000..3b7b6413a
--- /dev/null
+++ b/src/test/java/g3001_3100/s3093_longest_common_suffix_queries/SolutionTest.java
@@ -0,0 +1,28 @@
+package g3001_3100.s3093_longest_common_suffix_queries;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void stringIndices() {
+ assertThat(
+ new Solution()
+ .stringIndices(
+ new String[] {"abcd", "bcd", "xbcd"},
+ new String[] {"cd", "bcd", "xyz"}),
+ equalTo(new int[] {1, 1, 1}));
+ }
+
+ @Test
+ void stringIndices2() {
+ assertThat(
+ new Solution()
+ .stringIndices(
+ new String[] {"abcdefgh", "poiuygh", "ghghgh"},
+ new String[] {"gh", "acbfgh", "acbfegh"}),
+ equalTo(new int[] {2, 0, 2}));
+ }
+}
diff --git a/src/test/java/g3001_3100/s3095_shortest_subarray_with_or_at_least_k_i/SolutionTest.java b/src/test/java/g3001_3100/s3095_shortest_subarray_with_or_at_least_k_i/SolutionTest.java
new file mode 100644
index 000000000..d527eb611
--- /dev/null
+++ b/src/test/java/g3001_3100/s3095_shortest_subarray_with_or_at_least_k_i/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3001_3100.s3095_shortest_subarray_with_or_at_least_k_i;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void minimumSubarrayLength() {
+ assertThat(new Solution().minimumSubarrayLength(new int[] {1, 2, 3}, 2), equalTo(1));
+ }
+
+ @Test
+ void minimumSubarrayLength2() {
+ assertThat(new Solution().minimumSubarrayLength(new int[] {2, 1, 8}, 10), equalTo(3));
+ }
+
+ @Test
+ void minimumSubarrayLength3() {
+ assertThat(new Solution().minimumSubarrayLength(new int[] {1, 2}, 0), equalTo(1));
+ }
+}