From 08e35ca4b542751b2144184eb51f0433e1939a13 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 24 Sep 2024 04:43:23 +0300 Subject: [PATCH 1/3] Added tasks 3295-3298 --- .../s3295_report_spam_message/Solution.kt | 19 ++++++ .../s3295_report_spam_message/readme.md | 35 +++++++++++ .../Solution.kt | 33 ++++++++++ .../readme.md | 62 +++++++++++++++++++ .../Solution.kt | 45 ++++++++++++++ .../readme.md | 41 ++++++++++++ .../Solution.kt | 34 ++++++++++ .../readme.md | 43 +++++++++++++ .../s3295_report_spam_message/SolutionTest.kt | 31 ++++++++++ .../SolutionTest.kt | 31 ++++++++++ .../SolutionTest.kt | 28 +++++++++ .../SolutionTest.kt | 28 +++++++++ 12 files changed, 430 insertions(+) create mode 100644 src/main/kotlin/g3201_3300/s3295_report_spam_message/Solution.kt create mode 100644 src/main/kotlin/g3201_3300/s3295_report_spam_message/readme.md create mode 100644 src/main/kotlin/g3201_3300/s3296_minimum_number_of_seconds_to_make_mountain_height_zero/Solution.kt create mode 100644 src/main/kotlin/g3201_3300/s3296_minimum_number_of_seconds_to_make_mountain_height_zero/readme.md create mode 100644 src/main/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/Solution.kt create mode 100644 src/main/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/readme.md create mode 100644 src/main/kotlin/g3201_3300/s3298_count_substrings_that_can_be_rearranged_to_contain_a_string_ii/Solution.kt create mode 100644 src/main/kotlin/g3201_3300/s3298_count_substrings_that_can_be_rearranged_to_contain_a_string_ii/readme.md create mode 100644 src/test/kotlin/g3201_3300/s3295_report_spam_message/SolutionTest.kt create mode 100644 src/test/kotlin/g3201_3300/s3296_minimum_number_of_seconds_to_make_mountain_height_zero/SolutionTest.kt create mode 100644 src/test/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/SolutionTest.kt create mode 100644 src/test/kotlin/g3201_3300/s3298_count_substrings_that_can_be_rearranged_to_contain_a_string_ii/SolutionTest.kt diff --git a/src/main/kotlin/g3201_3300/s3295_report_spam_message/Solution.kt b/src/main/kotlin/g3201_3300/s3295_report_spam_message/Solution.kt new file mode 100644 index 000000000..48b977bfe --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3295_report_spam_message/Solution.kt @@ -0,0 +1,19 @@ +package g3201_3300.s3295_report_spam_message + +// #Medium #Array #String #Hash_Table #2024_09_24_Time_782_ms_(74.19%)_Space_109.6_MB_(38.71%) + +class Solution { + fun reportSpam(message: Array, bannedWords: Array): Boolean { + val bannedUnique: MutableSet = mutableSetOf(*bannedWords) + var bannedCount = 0 + for (msg in message) { + if (bannedUnique.contains(msg)) { + bannedCount++ + } + if (bannedCount == 2) { + return true + } + } + return false + } +} diff --git a/src/main/kotlin/g3201_3300/s3295_report_spam_message/readme.md b/src/main/kotlin/g3201_3300/s3295_report_spam_message/readme.md new file mode 100644 index 000000000..8b12c226f --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3295_report_spam_message/readme.md @@ -0,0 +1,35 @@ +3295\. Report Spam Message + +Medium + +You are given an array of strings `message` and an array of strings `bannedWords`. + +An array of words is considered **spam** if there are **at least** two words in it that **exactly** match any word in `bannedWords`. + +Return `true` if the array `message` is spam, and `false` otherwise. + +**Example 1:** + +**Input:** message = ["hello","world","leetcode"], bannedWords = ["world","hello"] + +**Output:** true + +**Explanation:** + +The words `"hello"` and `"world"` from the `message` array both appear in the `bannedWords` array. + +**Example 2:** + +**Input:** message = ["hello","programming","fun"], bannedWords = ["world","programming","leetcode"] + +**Output:** false + +**Explanation:** + +Only one word from the `message` array (`"programming"`) appears in the `bannedWords` array. + +**Constraints:** + +* 1 <= message.length, bannedWords.length <= 105 +* `1 <= message[i].length, bannedWords[i].length <= 15` +* `message[i]` and `bannedWords[i]` consist only of lowercase English letters. \ No newline at end of file diff --git a/src/main/kotlin/g3201_3300/s3296_minimum_number_of_seconds_to_make_mountain_height_zero/Solution.kt b/src/main/kotlin/g3201_3300/s3296_minimum_number_of_seconds_to_make_mountain_height_zero/Solution.kt new file mode 100644 index 000000000..14236ca56 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3296_minimum_number_of_seconds_to_make_mountain_height_zero/Solution.kt @@ -0,0 +1,33 @@ +package g3201_3300.s3296_minimum_number_of_seconds_to_make_mountain_height_zero + +// #Medium #Array #Math #Binary_Search #2024_09_24_Time_228_ms_(87.50%)_Space_38.6_MB_(81.25%) + +import kotlin.math.sqrt + +class Solution { + fun minNumberOfSeconds(mountainHeight: Int, workerTimes: IntArray): Long { + var left: Long = 0 + var right = mountainHeight.toLong() * (mountainHeight + 1) / 2 * workerTimes[0] + while (left < right) { + val mid = left + (right - left) / 2 + if (canReduceMountain(workerTimes, mountainHeight, mid)) { + right = mid + } else { + left = mid + 1 + } + } + return left + } + + private fun canReduceMountain(workerTimes: IntArray, mountainHeight: Int, timeLimit: Long): Boolean { + var totalHeightReduced: Long = 0 + for (workerTime in workerTimes) { + val maxHeightThisWorker = (sqrt(2.0 * timeLimit / workerTime + 0.25) - 0.5).toLong() + totalHeightReduced += maxHeightThisWorker + if (totalHeightReduced >= mountainHeight) { + return true + } + } + return totalHeightReduced >= mountainHeight + } +} diff --git a/src/main/kotlin/g3201_3300/s3296_minimum_number_of_seconds_to_make_mountain_height_zero/readme.md b/src/main/kotlin/g3201_3300/s3296_minimum_number_of_seconds_to_make_mountain_height_zero/readme.md new file mode 100644 index 000000000..2b6af89d0 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3296_minimum_number_of_seconds_to_make_mountain_height_zero/readme.md @@ -0,0 +1,62 @@ +3296\. Minimum Number of Seconds to Make Mountain Height Zero + +Medium + +You are given an integer `mountainHeight` denoting the height of a mountain. + +You are also given an integer array `workerTimes` representing the work time of workers in **seconds**. + +The workers work **simultaneously** to **reduce** the height of the mountain. For worker `i`: + +* To decrease the mountain's height by `x`, it takes `workerTimes[i] + workerTimes[i] * 2 + ... + workerTimes[i] * x` seconds. For example: + * To reduce the height of the mountain by 1, it takes `workerTimes[i]` seconds. + * To reduce the height of the mountain by 2, it takes `workerTimes[i] + workerTimes[i] * 2` seconds, and so on. + +Return an integer representing the **minimum** number of seconds required for the workers to make the height of the mountain 0. + +**Example 1:** + +**Input:** mountainHeight = 4, workerTimes = [2,1,1] + +**Output:** 3 + +**Explanation:** + +One way the height of the mountain can be reduced to 0 is: + +* Worker 0 reduces the height by 1, taking `workerTimes[0] = 2` seconds. +* Worker 1 reduces the height by 2, taking `workerTimes[1] + workerTimes[1] * 2 = 3` seconds. +* Worker 2 reduces the height by 1, taking `workerTimes[2] = 1` second. + +Since they work simultaneously, the minimum time needed is `max(2, 3, 1) = 3` seconds. + +**Example 2:** + +**Input:** mountainHeight = 10, workerTimes = [3,2,2,4] + +**Output:** 12 + +**Explanation:** + +* Worker 0 reduces the height by 2, taking `workerTimes[0] + workerTimes[0] * 2 = 9` seconds. +* Worker 1 reduces the height by 3, taking `workerTimes[1] + workerTimes[1] * 2 + workerTimes[1] * 3 = 12` seconds. +* Worker 2 reduces the height by 3, taking `workerTimes[2] + workerTimes[2] * 2 + workerTimes[2] * 3 = 12` seconds. +* Worker 3 reduces the height by 2, taking `workerTimes[3] + workerTimes[3] * 2 = 12` seconds. + +The number of seconds needed is `max(9, 12, 12, 12) = 12` seconds. + +**Example 3:** + +**Input:** mountainHeight = 5, workerTimes = [1] + +**Output:** 15 + +**Explanation:** + +There is only one worker in this example, so the answer is `workerTimes[0] + workerTimes[0] * 2 + workerTimes[0] * 3 + workerTimes[0] * 4 + workerTimes[0] * 5 = 15`. + +**Constraints:** + +* 1 <= mountainHeight <= 105 +* 1 <= workerTimes.length <= 104 +* 1 <= workerTimes[i] <= 106 \ No newline at end of file diff --git a/src/main/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/Solution.kt b/src/main/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/Solution.kt new file mode 100644 index 000000000..f321d3951 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/Solution.kt @@ -0,0 +1,45 @@ +package g3201_3300.s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i + +// #Medium #String #Hash_Table #Sliding_Window +// #2024_09_24_Time_215_ms_(93.33%)_Space_38.2_MB_(93.33%) + +class Solution { + fun validSubstringCount(word1: String, word2: String): Long { + var res: Long = 0 + var keys = 0 + val len = word1.length + val count = IntArray(26) + val letters = BooleanArray(26) + for (letter in word2.toCharArray()) { + val index = letter.code - 'a'.code + if (count[index]++ == 0) { + letters[index] = true + keys++ + } + } + var start = 0 + var end = 0 + while (end < len) { + val index = word1.get(end).code - 'a'.code + if (!letters[index]) { + end++ + continue + } + if (--count[index] == 0) { + --keys + } + while (keys == 0) { + res += (len - end).toLong() + val beginIndex = word1.get(start++).code - 'a'.code + if (!letters[beginIndex]) { + continue + } + if (count[beginIndex]++ == 0) { + keys++ + } + } + end++ + } + return res + } +} diff --git a/src/main/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/readme.md b/src/main/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/readme.md new file mode 100644 index 000000000..59ffeb4b1 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/readme.md @@ -0,0 +1,41 @@ +3297\. Count Substrings That Can Be Rearranged to Contain a String I + +Medium + +You are given two strings `word1` and `word2`. + +A string `x` is called **valid** if `x` can be rearranged to have `word2` as a prefix. + +Return the total number of **valid** substrings of `word1`. + +**Example 1:** + +**Input:** word1 = "bcca", word2 = "abc" + +**Output:** 1 + +**Explanation:** + +The only valid substring is `"bcca"` which can be rearranged to `"abcc"` having `"abc"` as a prefix. + +**Example 2:** + +**Input:** word1 = "abcabc", word2 = "abc" + +**Output:** 10 + +**Explanation:** + +All the substrings except substrings of size 1 and size 2 are valid. + +**Example 3:** + +**Input:** word1 = "abcabc", word2 = "aaabc" + +**Output:** 0 + +**Constraints:** + +* 1 <= word1.length <= 105 +* 1 <= word2.length <= 104 +* `word1` and `word2` consist only of lowercase English letters. \ No newline at end of file diff --git a/src/main/kotlin/g3201_3300/s3298_count_substrings_that_can_be_rearranged_to_contain_a_string_ii/Solution.kt b/src/main/kotlin/g3201_3300/s3298_count_substrings_that_can_be_rearranged_to_contain_a_string_ii/Solution.kt new file mode 100644 index 000000000..c5085b377 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3298_count_substrings_that_can_be_rearranged_to_contain_a_string_ii/Solution.kt @@ -0,0 +1,34 @@ +package g3201_3300.s3298_count_substrings_that_can_be_rearranged_to_contain_a_string_ii + +// #Hard #String #Hash_Table #Sliding_Window #2024_09_24_Time_433_ms_(78.57%)_Space_51.9_MB_(42.86%) + +class Solution { + fun validSubstringCount(word1: String, word2: String): Long { + val ar = word1.toCharArray() + val n = ar.size + val temp = word2.toCharArray() + val f = IntArray(26) + for (i in temp) { + f[i.code - 97]++ + } + var ans: Long = 0 + var needed = temp.size + var beg = 0 + var end = 0 + while (end < n) { + if (f[ar[end].code - 97]-- > 0) { + needed-- + } + while (needed == 0) { + // All substrings from [beg, i], where end <= i < n are valid + ans += (n - end).toLong() + // Shrink + if (f[ar[beg++].code - 97]++ == 0) { + needed++ + } + } + end++ + } + return ans + } +} diff --git a/src/main/kotlin/g3201_3300/s3298_count_substrings_that_can_be_rearranged_to_contain_a_string_ii/readme.md b/src/main/kotlin/g3201_3300/s3298_count_substrings_that_can_be_rearranged_to_contain_a_string_ii/readme.md new file mode 100644 index 000000000..510e437e6 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3298_count_substrings_that_can_be_rearranged_to_contain_a_string_ii/readme.md @@ -0,0 +1,43 @@ +3298\. Count Substrings That Can Be Rearranged to Contain a String II + +Hard + +You are given two strings `word1` and `word2`. + +A string `x` is called **valid** if `x` can be rearranged to have `word2` as a prefix. + +Return the total number of **valid** substrings of `word1`. + +**Note** that the memory limits in this problem are **smaller** than usual, so you **must** implement a solution with a _linear_ runtime complexity. + +**Example 1:** + +**Input:** word1 = "bcca", word2 = "abc" + +**Output:** 1 + +**Explanation:** + +The only valid substring is `"bcca"` which can be rearranged to `"abcc"` having `"abc"` as a prefix. + +**Example 2:** + +**Input:** word1 = "abcabc", word2 = "abc" + +**Output:** 10 + +**Explanation:** + +All the substrings except substrings of size 1 and size 2 are valid. + +**Example 3:** + +**Input:** word1 = "abcabc", word2 = "aaabc" + +**Output:** 0 + +**Constraints:** + +* 1 <= word1.length <= 106 +* 1 <= word2.length <= 104 +* `word1` and `word2` consist only of lowercase English letters. \ No newline at end of file diff --git a/src/test/kotlin/g3201_3300/s3295_report_spam_message/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3295_report_spam_message/SolutionTest.kt new file mode 100644 index 000000000..b82f54317 --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3295_report_spam_message/SolutionTest.kt @@ -0,0 +1,31 @@ +package g3201_3300.s3295_report_spam_message + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun reportSpam() { + assertThat( + Solution() + .reportSpam( + arrayOf("hello", "world", "leetcode"), + arrayOf("world", "hello") + ), + equalTo(true) + ) + } + + @Test + fun reportSpam2() { + assertThat( + Solution() + .reportSpam( + arrayOf("hello", "programming", "fun"), + arrayOf("world", "programming", "leetcode") + ), + equalTo(false) + ) + } +} diff --git a/src/test/kotlin/g3201_3300/s3296_minimum_number_of_seconds_to_make_mountain_height_zero/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3296_minimum_number_of_seconds_to_make_mountain_height_zero/SolutionTest.kt new file mode 100644 index 000000000..f5e7e1656 --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3296_minimum_number_of_seconds_to_make_mountain_height_zero/SolutionTest.kt @@ -0,0 +1,31 @@ +package g3201_3300.s3296_minimum_number_of_seconds_to_make_mountain_height_zero + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun minNumberOfSeconds() { + assertThat( + Solution().minNumberOfSeconds(4, intArrayOf(2, 1, 1)), + equalTo(3L) + ) + } + + @Test + fun minNumberOfSeconds2() { + assertThat( + Solution().minNumberOfSeconds(10, intArrayOf(3, 2, 2, 4)), + equalTo(12L) + ) + } + + @Test + fun minNumberOfSeconds3() { + assertThat( + Solution().minNumberOfSeconds(5, intArrayOf(1)), + equalTo(15L) + ) + } +} diff --git a/src/test/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/SolutionTest.kt new file mode 100644 index 000000000..f4deff51a --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/SolutionTest.kt @@ -0,0 +1,28 @@ +package g3201_3300.s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun validSubstringCount() { + assertThat(Solution().validSubstringCount("bcca", "abc"), equalTo(1L)) + } + + @Test + fun validSubstringCount2() { + assertThat( + Solution().validSubstringCount("abcabc", "abc"), + equalTo(10L) + ) + } + + @Test + fun validSubstringCount3() { + assertThat( + Solution().validSubstringCount("abcabc", "aaabc"), + equalTo(0L) + ) + } +} diff --git a/src/test/kotlin/g3201_3300/s3298_count_substrings_that_can_be_rearranged_to_contain_a_string_ii/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3298_count_substrings_that_can_be_rearranged_to_contain_a_string_ii/SolutionTest.kt new file mode 100644 index 000000000..bac0ad779 --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3298_count_substrings_that_can_be_rearranged_to_contain_a_string_ii/SolutionTest.kt @@ -0,0 +1,28 @@ +package g3201_3300.s3298_count_substrings_that_can_be_rearranged_to_contain_a_string_ii + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun validSubstringCount() { + assertThat(Solution().validSubstringCount("bcca", "abc"), equalTo(1L)) + } + + @Test + fun validSubstringCount2() { + assertThat( + Solution().validSubstringCount("abcabc", "abc"), + equalTo(10L) + ) + } + + @Test + fun validSubstringCount3() { + assertThat( + Solution().validSubstringCount("abcabc", "aaabc"), + equalTo(0L) + ) + } +} From 70f19c2152c5e26c9830b622f847ce5fe26213ba Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 24 Sep 2024 04:51:06 +0300 Subject: [PATCH 2/3] fixed sonar --- .../Solution.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/Solution.kt b/src/main/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/Solution.kt index f321d3951..169bb0257 100644 --- a/src/main/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/Solution.kt +++ b/src/main/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/Solution.kt @@ -20,7 +20,7 @@ class Solution { var start = 0 var end = 0 while (end < len) { - val index = word1.get(end).code - 'a'.code + val index = word1[end].code - 'a'.code if (!letters[index]) { end++ continue @@ -30,7 +30,7 @@ class Solution { } while (keys == 0) { res += (len - end).toLong() - val beginIndex = word1.get(start++).code - 'a'.code + val beginIndex = word1[start++].code - 'a'.code if (!letters[beginIndex]) { continue } From b3dd3fff1d6b6b31b560cfb8bf258b9566fe2237 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 24 Sep 2024 04:59:39 +0300 Subject: [PATCH 3/3] Added test --- .../SolutionTest.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/SolutionTest.kt index f4deff51a..71967ccc3 100644 --- a/src/test/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/SolutionTest.kt +++ b/src/test/kotlin/g3201_3300/s3297_count_substrings_that_can_be_rearranged_to_contain_a_string_i/SolutionTest.kt @@ -25,4 +25,12 @@ internal class SolutionTest { equalTo(0L) ) } + + @Test + fun validSubstringCount4() { + assertThat( + Solution().validSubstringCount("dcbdcdccb", "cdd"), + equalTo(18L) + ) + } }