From 3b6335da8ecf6b4c92ad41f8e917f0012f9d20a8 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 15 Nov 2024 07:54:41 +0200 Subject: [PATCH 1/2] Added tasks 3349-3352 --- .../Solution.kt | 27 ++++++++++ .../readme.md | 34 ++++++++++++ .../Solution.kt | 33 ++++++++++++ .../readme.md | 41 ++++++++++++++ .../Solution.kt | 26 +++++++++ .../s3351_sum_of_good_subsequences/readme.md | 38 +++++++++++++ .../Solution.kt | 39 ++++++++++++++ .../readme.md | 54 +++++++++++++++++++ .../SolutionTest.kt | 23 ++++++++ .../SolutionTest.kt | 23 ++++++++ .../SolutionTest.kt | 23 ++++++++ .../SolutionTest.kt | 22 ++++++++ 12 files changed, 383 insertions(+) create mode 100644 src/main/kotlin/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/Solution.kt create mode 100644 src/main/kotlin/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/readme.md create mode 100644 src/main/kotlin/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/Solution.kt create mode 100644 src/main/kotlin/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/readme.md create mode 100644 src/main/kotlin/g3301_3400/s3351_sum_of_good_subsequences/Solution.kt create mode 100644 src/main/kotlin/g3301_3400/s3351_sum_of_good_subsequences/readme.md create mode 100644 src/main/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/Solution.kt create mode 100644 src/main/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/readme.md create mode 100644 src/test/kotlin/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/SolutionTest.kt create mode 100644 src/test/kotlin/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/SolutionTest.kt create mode 100644 src/test/kotlin/g3301_3400/s3351_sum_of_good_subsequences/SolutionTest.kt create mode 100644 src/test/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/SolutionTest.kt diff --git a/src/main/kotlin/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/Solution.kt b/src/main/kotlin/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/Solution.kt new file mode 100644 index 000000000..54c34bce7 --- /dev/null +++ b/src/main/kotlin/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/Solution.kt @@ -0,0 +1,27 @@ +package g3301_3400.s3349_adjacent_increasing_subarrays_detection_i + +// #Easy #Array #2024_11_15_Time_179_ms_(97.92%)_Space_37.3_MB_(91.67%) + +class Solution { + fun hasIncreasingSubarrays(nums: List, k: Int): Boolean { + val l = nums.size + if (l < k * 2) { + return false + } + for (i in 0.rangeUntil(l - 2 * k + 1)) { + if (check(i, k, nums) && check(i + k, k, nums)) { + return true + } + } + return false + } + + private fun check(p: Int, k: Int, nums: List): Boolean { + for (i in p.rangeUntil(p + k - 1)) { + if (nums[i] >= nums[i + 1]) { + return false + } + } + return true + } +} diff --git a/src/main/kotlin/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/readme.md b/src/main/kotlin/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/readme.md new file mode 100644 index 000000000..9bf001ccf --- /dev/null +++ b/src/main/kotlin/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/kotlin/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/Solution.kt b/src/main/kotlin/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/Solution.kt new file mode 100644 index 000000000..c05dc83a4 --- /dev/null +++ b/src/main/kotlin/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/Solution.kt @@ -0,0 +1,33 @@ +package g3301_3400.s3350_adjacent_increasing_subarrays_detection_ii + +// #Medium #Array #Binary_Search #2024_11_15_Time_947_ms_(48.57%)_Space_87.4_MB_(51.43%) + +import kotlin.math.max +import kotlin.math.min + +class Solution { + fun maxIncreasingSubarrays(nums: List): Int { + val n = nums.size + val a = IntArray(n) + for (i in 0.rangeUntil(n)) { + a[i] = nums[i] + } + var ans = 1 + var previousLen = Int.Companion.MAX_VALUE + var i = 0 + while (i < n) { + var j = i + 1 + while (j < n && a[j - 1] < a[j]) { + ++j + } + val len = j - i + ans = max(ans, (len / 2)) + if (previousLen != Int.Companion.MAX_VALUE) { + ans = max(ans, min(previousLen, len)) + } + previousLen = len + i = j + } + return ans + } +} diff --git a/src/main/kotlin/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/readme.md b/src/main/kotlin/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/readme.md new file mode 100644 index 000000000..4742353ee --- /dev/null +++ b/src/main/kotlin/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/kotlin/g3301_3400/s3351_sum_of_good_subsequences/Solution.kt b/src/main/kotlin/g3301_3400/s3351_sum_of_good_subsequences/Solution.kt new file mode 100644 index 000000000..0f09a4638 --- /dev/null +++ b/src/main/kotlin/g3301_3400/s3351_sum_of_good_subsequences/Solution.kt @@ -0,0 +1,26 @@ +package g3301_3400.s3351_sum_of_good_subsequences + +// #Hard #Array #Hash_Table #Dynamic_Programming +// #2024_11_15_Time_16_ms_(100.00%)_Space_61.2_MB_(80.00%) + +import kotlin.math.max + +class Solution { + fun sumOfGoodSubsequences(nums: IntArray): Int { + var max = 0 + for (x in nums) { + max = max(x, max) + } + val count = LongArray(max + 3) + val total = LongArray(max + 3) + val mod = (1e9 + 7).toInt().toLong() + var res: Long = 0 + for (a in nums) { + count[a + 1] = (count[a] + count[a + 1] + count[a + 2] + 1) % mod + val 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 res.toInt() + } +} diff --git a/src/main/kotlin/g3301_3400/s3351_sum_of_good_subsequences/readme.md b/src/main/kotlin/g3301_3400/s3351_sum_of_good_subsequences/readme.md new file mode 100644 index 000000000..17909b132 --- /dev/null +++ b/src/main/kotlin/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/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/Solution.kt b/src/main/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/Solution.kt new file mode 100644 index 000000000..edeadef52 --- /dev/null +++ b/src/main/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/Solution.kt @@ -0,0 +1,39 @@ +package g3301_3400.s3352_count_k_reducible_numbers_less_than_n + +// #Hard #String #Dynamic_Programming #Math #Combinatorics +// #2024_11_15_Time_170_ms_(100.00%)_Space_34.9_MB_(100.00%) + +class Solution { + fun countKReducibleNumbers(s: String, k: Int): Int { + val n = s.length + val reducible = IntArray(n + 1) + for (i in 2.rangeUntil(reducible.size)) { + reducible[i] = 1 + reducible[Integer.bitCount(i)] + } + val dp = LongArray(n + 1) + var curr = 0 + for (i in 0.rangeUntil(n)) { + for (j in i - 1 downTo 0) { + dp[j + 1] += dp[j] + dp[j + 1] %= MOD.toLong() + } + if (s.get(i) == '1') { + dp[curr]++ + dp[curr] %= MOD.toLong() + curr++ + } + } + var result: Long = 0 + for (i in 1..s.length) { + if (reducible[i] < k) { + result += dp[i] + result %= MOD.toLong() + } + } + return (result % MOD).toInt() + } + + companion object { + private val MOD = (1e9 + 7).toInt() + } +} diff --git a/src/main/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/readme.md b/src/main/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/readme.md new file mode 100644 index 000000000..1f4a28a23 --- /dev/null +++ b/src/main/kotlin/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/kotlin/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/SolutionTest.kt b/src/test/kotlin/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/SolutionTest.kt new file mode 100644 index 000000000..91b7d6071 --- /dev/null +++ b/src/test/kotlin/g3301_3400/s3349_adjacent_increasing_subarrays_detection_i/SolutionTest.kt @@ -0,0 +1,23 @@ +package g3301_3400.s3349_adjacent_increasing_subarrays_detection_i + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun hasIncreasingSubarrays() { + assertThat( + Solution().hasIncreasingSubarrays(listOf(2, 5, 7, 8, 9, 2, 3, 4, 3, 1), 3), + equalTo(true) + ) + } + + @Test + fun hasIncreasingSubarrays2() { + assertThat( + Solution().hasIncreasingSubarrays(listOf(1, 2, 3, 4, 4, 4, 4, 5, 6, 7), 5), + equalTo(false) + ) + } +} diff --git a/src/test/kotlin/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/SolutionTest.kt b/src/test/kotlin/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/SolutionTest.kt new file mode 100644 index 000000000..5985b54ff --- /dev/null +++ b/src/test/kotlin/g3301_3400/s3350_adjacent_increasing_subarrays_detection_ii/SolutionTest.kt @@ -0,0 +1,23 @@ +package g3301_3400.s3350_adjacent_increasing_subarrays_detection_ii + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun maxIncreasingSubarrays() { + assertThat( + Solution().maxIncreasingSubarrays(listOf(2, 5, 7, 8, 9, 2, 3, 4, 3, 1)), + equalTo(3) + ) + } + + @Test + fun maxIncreasingSubarrays2() { + assertThat( + Solution().maxIncreasingSubarrays(listOf(1, 2, 3, 4, 4, 4, 4, 5, 6, 7)), + equalTo(2) + ) + } +} diff --git a/src/test/kotlin/g3301_3400/s3351_sum_of_good_subsequences/SolutionTest.kt b/src/test/kotlin/g3301_3400/s3351_sum_of_good_subsequences/SolutionTest.kt new file mode 100644 index 000000000..06db76958 --- /dev/null +++ b/src/test/kotlin/g3301_3400/s3351_sum_of_good_subsequences/SolutionTest.kt @@ -0,0 +1,23 @@ +package g3301_3400.s3351_sum_of_good_subsequences + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun sumOfGoodSubsequences() { + assertThat( + Solution().sumOfGoodSubsequences(intArrayOf(1, 2, 1)), + equalTo(14) + ) + } + + @Test + fun sumOfGoodSubsequences2() { + assertThat( + Solution().sumOfGoodSubsequences(intArrayOf(3, 4, 5)), + equalTo(40) + ) + } +} diff --git a/src/test/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/SolutionTest.kt b/src/test/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/SolutionTest.kt new file mode 100644 index 000000000..212b67270 --- /dev/null +++ b/src/test/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/SolutionTest.kt @@ -0,0 +1,22 @@ +package g3301_3400.s3352_count_k_reducible_numbers_less_than_n + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun countKReducibleNumbers() { + assertThat(Solution().countKReducibleNumbers("111", 1), equalTo(3)) + } + + @Test + fun countKReducibleNumbers2() { + assertThat(Solution().countKReducibleNumbers("1000", 2), equalTo(6)) + } + + @Test + fun countKReducibleNumbers3() { + assertThat(Solution().countKReducibleNumbers("1", 3), equalTo(0)) + } +} From 30ebbf297f6997627f1b2376281f1a03e6845f66 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 15 Nov 2024 10:13:00 +0200 Subject: [PATCH 2/2] Fixed sonar --- .../s3352_count_k_reducible_numbers_less_than_n/Solution.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/Solution.kt b/src/main/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/Solution.kt index edeadef52..f01eb4176 100644 --- a/src/main/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/Solution.kt +++ b/src/main/kotlin/g3301_3400/s3352_count_k_reducible_numbers_less_than_n/Solution.kt @@ -17,7 +17,7 @@ class Solution { dp[j + 1] += dp[j] dp[j + 1] %= MOD.toLong() } - if (s.get(i) == '1') { + if (s[i] == '1') { dp[curr]++ dp[curr] %= MOD.toLong() curr++