diff --git a/src/main/java/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/Solution.java b/src/main/java/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/Solution.java new file mode 100644 index 000000000..804c6fcd2 --- /dev/null +++ b/src/main/java/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/Solution.java @@ -0,0 +1,29 @@ +package g3301_3400.s3349_adjacent_increasing_subarrays_detection_i; + +// #Easy #Array #2024_11_15_Time_1_ms_(100.00%)_Space_44.7_MB_(18.69%) + +import java.util.List; + +public class Solution { + public boolean hasIncreasingSubarrays(List nums, int k) { + int l = nums.size(); + if (l < k * 2) { + return false; + } + for (int i = 0; i < l - 2 * k + 1; i++) { + if (check(i, k, nums) && check(i + k, k, nums)) { + return true; + } + } + return false; + } + + private boolean check(int p, int k, List nums) { + for (int i = p; i < p + k - 1; i++) { + if (nums.get(i) >= nums.get(i + 1)) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/readme.md b/src/main/java/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/readme.md new file mode 100644 index 000000000..9bf001ccf --- /dev/null +++ b/src/main/java/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/readme.md @@ -0,0 +1,34 @@ +3349\. Adjacent Increasing Subarrays Detection I + +Easy + +Given an array `nums` of `n` integers and an integer `k`, determine whether there exist **two** **adjacent** subarrays of length `k` such that both subarrays are **strictly** **increasing**. Specifically, check if there are **two** subarrays starting at indices `a` and `b` (`a < b`), where: + +* Both subarrays `nums[a..a + k - 1]` and `nums[b..b + k - 1]` are **strictly increasing**. +* The subarrays must be **adjacent**, meaning `b = a + k`. + +Return `true` if it is _possible_ to find **two** such subarrays, and `false` otherwise. + +**Example 1:** + +**Input:** nums = [2,5,7,8,9,2,3,4,3,1], k = 3 + +**Output:** true + +**Explanation:** + +* The subarray starting at index `2` is `[7, 8, 9]`, which is strictly increasing. +* The subarray starting at index `5` is `[2, 3, 4]`, which is also strictly increasing. +* These two subarrays are adjacent, so the result is `true`. + +**Example 2:** + +**Input:** nums = [1,2,3,4,4,4,4,5,6,7], k = 5 + +**Output:** false + +**Constraints:** + +* `2 <= nums.length <= 100` +* `1 < 2 * k <= nums.length` +* `-1000 <= nums[i] <= 1000` \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/Solution.java b/src/main/java/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/Solution.java new file mode 100644 index 000000000..66e847d33 --- /dev/null +++ b/src/main/java/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/Solution.java @@ -0,0 +1,32 @@ +package g3301_3400.s3350_adjacent_increasing_subarrays_detection_ii; + +// #Medium #Array #Binary_Search #2024_11_15_Time_10_ms_(99.76%)_Space_90.6_MB_(30.61%) + +import java.util.List; + +public class Solution { + public int maxIncreasingSubarrays(List nums) { + int n = nums.size(); + int[] a = new int[n]; + for (int i = 0; i < n; ++i) { + a[i] = nums.get(i); + } + int ans = 1; + int previousLen = Integer.MAX_VALUE; + int i = 0; + while (i < n) { + int j = i + 1; + while (j < n && a[j - 1] < a[j]) { + ++j; + } + int len = j - i; + ans = Math.max(ans, len / 2); + if (previousLen != Integer.MAX_VALUE) { + ans = Math.max(ans, Math.min(previousLen, len)); + } + previousLen = len; + i = j; + } + return ans; + } +} diff --git a/src/main/java/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/readme.md b/src/main/java/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/readme.md new file mode 100644 index 000000000..4742353ee --- /dev/null +++ b/src/main/java/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/readme.md @@ -0,0 +1,41 @@ +3350\. Adjacent Increasing Subarrays Detection II + +Medium + +Given an array `nums` of `n` integers, your task is to find the **maximum** value of `k` for which there exist **two** adjacent subarrays of length `k` each, such that both subarrays are **strictly** **increasing**. Specifically, check if there are **two** subarrays of length `k` starting at indices `a` and `b` (`a < b`), where: + +* Both subarrays `nums[a..a + k - 1]` and `nums[b..b + k - 1]` are **strictly increasing**. +* The subarrays must be **adjacent**, meaning `b = a + k`. + +Return the **maximum** _possible_ value of `k`. + +A **subarray** is a contiguous **non-empty** sequence of elements within an array. + +**Example 1:** + +**Input:** nums = [2,5,7,8,9,2,3,4,3,1] + +**Output:** 3 + +**Explanation:** + +* The subarray starting at index 2 is `[7, 8, 9]`, which is strictly increasing. +* The subarray starting at index 5 is `[2, 3, 4]`, which is also strictly increasing. +* These two subarrays are adjacent, and 3 is the **maximum** possible value of `k` for which two such adjacent strictly increasing subarrays exist. + +**Example 2:** + +**Input:** nums = [1,2,3,4,4,4,4,5,6,7] + +**Output:** 2 + +**Explanation:** + +* The subarray starting at index 0 is `[1, 2]`, which is strictly increasing. +* The subarray starting at index 2 is `[3, 4]`, which is also strictly increasing. +* These two subarrays are adjacent, and 2 is the **maximum** possible value of `k` for which two such adjacent strictly increasing subarrays exist. + +**Constraints:** + +* 2 <= nums.length <= 2 * 105 +* -109 <= nums[i] <= 109 \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3351_sum_of_good_subsequences/Solution.java b/src/main/java/g3301_3400/s3351_sum_of_good_subsequences/Solution.java new file mode 100644 index 000000000..6b3f7ac21 --- /dev/null +++ b/src/main/java/g3301_3400/s3351_sum_of_good_subsequences/Solution.java @@ -0,0 +1,24 @@ +package g3301_3400.s3351_sum_of_good_subsequences; + +// #Hard #Array #Hash_Table #Dynamic_Programming +// #2024_11_15_Time_13_ms_(99.09%)_Space_55.8_MB_(68.79%) + +public class Solution { + public int sumOfGoodSubsequences(int[] nums) { + int max = 0; + for (int x : nums) { + max = Math.max(x, max); + } + long[] count = new long[max + 3]; + long[] total = new long[max + 3]; + long mod = (int) (1e9 + 7); + long res = 0; + for (int a : nums) { + count[a + 1] = (count[a] + count[a + 1] + count[a + 2] + 1) % mod; + long cur = total[a] + total[a + 2] + a * (count[a] + count[a + 2] + 1); + total[a + 1] = (total[a + 1] + cur) % mod; + res = (res + cur) % mod; + } + return (int) res; + } +} diff --git a/src/main/java/g3301_3400/s3351_sum_of_good_subsequences/readme.md b/src/main/java/g3301_3400/s3351_sum_of_good_subsequences/readme.md new file mode 100644 index 000000000..17909b132 --- /dev/null +++ b/src/main/java/g3301_3400/s3351_sum_of_good_subsequences/readme.md @@ -0,0 +1,38 @@ +3351\. Sum of Good Subsequences + +Hard + +You are given an integer array `nums`. A **good** subsequence is defined as a subsequence of `nums` where the absolute difference between any **two** consecutive elements in the subsequence is **exactly** 1. + +Return the **sum** of all _possible_ **good subsequences** of `nums`. + +Since the answer may be very large, return it **modulo** 109 + 7. + +**Note** that a subsequence of size 1 is considered good by definition. + +**Example 1:** + +**Input:** nums = [1,2,1] + +**Output:** 14 + +**Explanation:** + +* Good subsequences are: `[1]`, `[2]`, `[1]`, `[1,2]`, `[2,1]`, `[1,2,1]`. +* The sum of elements in these subsequences is 14. + +**Example 2:** + +**Input:** nums = [3,4,5] + +**Output:** 40 + +**Explanation:** + +* Good subsequences are: `[3]`, `[4]`, `[5]`, `[3,4]`, `[4,5]`, `[3,4,5]`. +* The sum of elements in these subsequences is 40. + +**Constraints:** + +* 1 <= nums.length <= 105 +* 0 <= nums[i] <= 105 \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/Solution.java b/src/main/java/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/Solution.java new file mode 100644 index 000000000..64abab217 --- /dev/null +++ b/src/main/java/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/Solution.java @@ -0,0 +1,37 @@ +package g3301_3400.s3352_count_k_reducible_numbers_less_than_n; + +// #Hard #String #Dynamic_Programming #Math #Combinatorics +// #2024_11_15_Time_11_ms_(99.58%)_Space_42.6_MB_(95.85%) + +public class Solution { + private static final int MOD = (int) (1e9 + 7); + + public int countKReducibleNumbers(String s, int k) { + int n = s.length(); + int[] reducible = new int[n + 1]; + for (int i = 2; i < reducible.length; i++) { + reducible[i] = 1 + reducible[Integer.bitCount(i)]; + } + long[] dp = new long[n + 1]; + int curr = 0; + for (int i = 0; i < n; i++) { + for (int j = i - 1; j >= 0; j--) { + dp[j + 1] += dp[j]; + dp[j + 1] %= MOD; + } + if (s.charAt(i) == '1') { + dp[curr]++; + dp[curr] %= MOD; + curr++; + } + } + long result = 0; + for (int i = 1; i <= s.length(); i++) { + if (reducible[i] < k) { + result += dp[i]; + result %= MOD; + } + } + return (int) (result % MOD); + } +} diff --git a/src/main/java/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/readme.md b/src/main/java/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/readme.md new file mode 100644 index 000000000..1f4a28a23 --- /dev/null +++ b/src/main/java/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/readme.md @@ -0,0 +1,54 @@ +3352\. Count K-Reducible Numbers Less Than N + +Hard + +You are given a **binary** string `s` representing a number `n` in its binary form. + +You are also given an integer `k`. + +An integer `x` is called **k-reducible** if performing the following operation **at most** `k` times reduces it to 1: + +* Replace `x` with the **count** of set bits in its binary representation. + +For example, the binary representation of 6 is `"110"`. Applying the operation once reduces it to 2 (since `"110"` has two set bits). Applying the operation again to 2 (binary `"10"`) reduces it to 1 (since `"10"` has one set bit). + +Return an integer denoting the number of positive integers **less** than `n` that are **k-reducible**. + +Since the answer may be too large, return it **modulo** 109 + 7. + +**Example 1:** + +**Input:** s = "111", k = 1 + +**Output:** 3 + +**Explanation:** + +`n = 7`. The 1-reducible integers less than 7 are 1, 2, and 4. + +**Example 2:** + +**Input:** s = "1000", k = 2 + +**Output:** 6 + +**Explanation:** + +`n = 8`. The 2-reducible integers less than 8 are 1, 2, 3, 4, 5, and 6. + +**Example 3:** + +**Input:** s = "1", k = 3 + +**Output:** 0 + +**Explanation:** + +There are no positive integers less than `n = 1`, so the answer is 0. + +**Constraints:** + +* `1 <= s.length <= 800` +* `s` has no leading zeros. +* `s` consists only of the characters `'0'` and `'1'`. +* `1 <= k <= 5` \ No newline at end of file diff --git a/src/test/java/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/SolutionTest.java b/src/test/java/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/SolutionTest.java new file mode 100644 index 000000000..8188da550 --- /dev/null +++ b/src/test/java/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/SolutionTest.java @@ -0,0 +1,23 @@ +package g3301_3400.s3349_adjacent_increasing_subarrays_detection_i; + +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 hasIncreasingSubarrays() { + assertThat( + new Solution().hasIncreasingSubarrays(List.of(2, 5, 7, 8, 9, 2, 3, 4, 3, 1), 3), + equalTo(true)); + } + + @Test + void hasIncreasingSubarrays2() { + assertThat( + new Solution().hasIncreasingSubarrays(List.of(1, 2, 3, 4, 4, 4, 4, 5, 6, 7), 5), + equalTo(false)); + } +} diff --git a/src/test/java/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/SolutionTest.java b/src/test/java/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/SolutionTest.java new file mode 100644 index 000000000..b0ed36f70 --- /dev/null +++ b/src/test/java/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/SolutionTest.java @@ -0,0 +1,23 @@ +package g3301_3400.s3350_adjacent_increasing_subarrays_detection_ii; + +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 maxIncreasingSubarrays() { + assertThat( + new Solution().maxIncreasingSubarrays(List.of(2, 5, 7, 8, 9, 2, 3, 4, 3, 1)), + equalTo(3)); + } + + @Test + void maxIncreasingSubarrays2() { + assertThat( + new Solution().maxIncreasingSubarrays(List.of(1, 2, 3, 4, 4, 4, 4, 5, 6, 7)), + equalTo(2)); + } +} diff --git a/src/test/java/g3301_3400/s3351_sum_of_good_subsequences/SolutionTest.java b/src/test/java/g3301_3400/s3351_sum_of_good_subsequences/SolutionTest.java new file mode 100644 index 000000000..e6e0f428a --- /dev/null +++ b/src/test/java/g3301_3400/s3351_sum_of_good_subsequences/SolutionTest.java @@ -0,0 +1,18 @@ +package g3301_3400.s3351_sum_of_good_subsequences; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void sumOfGoodSubsequences() { + assertThat(new Solution().sumOfGoodSubsequences(new int[] {1, 2, 1}), equalTo(14)); + } + + @Test + void sumOfGoodSubsequences2() { + assertThat(new Solution().sumOfGoodSubsequences(new int[] {3, 4, 5}), equalTo(40)); + } +} diff --git a/src/test/java/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/SolutionTest.java b/src/test/java/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/SolutionTest.java new file mode 100644 index 000000000..48fe0afeb --- /dev/null +++ b/src/test/java/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/SolutionTest.java @@ -0,0 +1,23 @@ +package g3301_3400.s3352_count_k_reducible_numbers_less_than_n; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void countKReducibleNumbers() { + assertThat(new Solution().countKReducibleNumbers("111", 1), equalTo(3)); + } + + @Test + void countKReducibleNumbers2() { + assertThat(new Solution().countKReducibleNumbers("1000", 2), equalTo(6)); + } + + @Test + void countKReducibleNumbers3() { + assertThat(new Solution().countKReducibleNumbers("1", 3), equalTo(0)); + } +}