diff --git a/src/main/kotlin/g3201_3300/s3285_find_indices_of_stable_mountains/Solution.kt b/src/main/kotlin/g3201_3300/s3285_find_indices_of_stable_mountains/Solution.kt new file mode 100644 index 000000000..63ba3f616 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3285_find_indices_of_stable_mountains/Solution.kt @@ -0,0 +1,16 @@ +package g3201_3300.s3285_find_indices_of_stable_mountains + +// #Easy #Array #2024_09_17_Time_195_ms_(92.68%)_Space_37.5_MB_(48.78%) + +class Solution { + fun stableMountains(height: IntArray, threshold: Int): List { + val n = height.size + val list: MutableList = mutableListOf() + for (i in 0 until n - 1) { + if (height[i] > threshold) { + list.add(i + 1) + } + } + return list + } +} diff --git a/src/main/kotlin/g3201_3300/s3285_find_indices_of_stable_mountains/readme.md b/src/main/kotlin/g3201_3300/s3285_find_indices_of_stable_mountains/readme.md new file mode 100644 index 000000000..6f8a52271 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3285_find_indices_of_stable_mountains/readme.md @@ -0,0 +1,38 @@ +3285\. Find Indices of Stable Mountains + +Easy + +There are `n` mountains in a row, and each mountain has a height. You are given an integer array `height` where `height[i]` represents the height of mountain `i`, and an integer `threshold`. + +A mountain is called **stable** if the mountain just before it (**if it exists**) has a height **strictly greater** than `threshold`. **Note** that mountain 0 is **not** stable. + +Return an array containing the indices of _all_ **stable** mountains in **any** order. + +**Example 1:** + +**Input:** height = [1,2,3,4,5], threshold = 2 + +**Output:** [3,4] + +**Explanation:** + +* Mountain 3 is stable because `height[2] == 3` is greater than `threshold == 2`. +* Mountain 4 is stable because `height[3] == 4` is greater than `threshold == 2`. + +**Example 2:** + +**Input:** height = [10,1,10,1,10], threshold = 3 + +**Output:** [1,3] + +**Example 3:** + +**Input:** height = [10,1,10,1,10], threshold = 10 + +**Output:** [] + +**Constraints:** + +* `2 <= n == height.length <= 100` +* `1 <= height[i] <= 100` +* `1 <= threshold <= 100` \ No newline at end of file diff --git a/src/main/kotlin/g3201_3300/s3286_find_a_safe_walk_through_a_grid/Solution.kt b/src/main/kotlin/g3201_3300/s3286_find_a_safe_walk_through_a_grid/Solution.kt new file mode 100644 index 000000000..56f109835 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3286_find_a_safe_walk_through_a_grid/Solution.kt @@ -0,0 +1,49 @@ +package g3201_3300.s3286_find_a_safe_walk_through_a_grid + +// #Medium #Array #Breadth_First_Search #Matrix #Heap_Priority_Queue #Graph #Shortest_Path +// #2024_09_17_Time_357_ms_(48.28%)_Space_48.2_MB_(58.62%) + +import java.util.LinkedList +import java.util.Objects +import java.util.Queue + +class Solution { + fun findSafeWalk(grid: List>, health: Int): Boolean { + val n = grid.size + val m = grid[0].size + val dr = intArrayOf(0, 0, 1, -1) + val dc = intArrayOf(1, -1, 0, 0) + val visited = Array?>(n) { Array(m) { BooleanArray(health + 1) } } + val bfs: Queue = LinkedList() + bfs.add(intArrayOf(0, 0, health - grid[0][0])) + visited[0]!![0][health - grid[0][0]] = true + while (bfs.isNotEmpty()) { + var size = bfs.size + while (size-- > 0) { + val currNode = bfs.poll() + val r = Objects.requireNonNull(currNode)[0] + val c = currNode!![1] + val h = currNode[2] + if (r == n - 1 && c == m - 1 && h > 0) { + return true + } + for (k in 0..3) { + val nr = r + dr[k] + val nc = c + dc[k] + if (isValidMove(nr, nc, n, m)) { + val nh: Int = h - grid[nr][nc] + if (nh >= 0 && !visited[nr]!![nc][nh]) { + visited[nr]!![nc][nh] = true + bfs.add(intArrayOf(nr, nc, nh)) + } + } + } + } + } + return false + } + + private fun isValidMove(r: Int, c: Int, n: Int, m: Int): Boolean { + return r >= 0 && c >= 0 && r < n && c < m + } +} diff --git a/src/main/kotlin/g3201_3300/s3286_find_a_safe_walk_through_a_grid/readme.md b/src/main/kotlin/g3201_3300/s3286_find_a_safe_walk_through_a_grid/readme.md new file mode 100644 index 000000000..331587234 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3286_find_a_safe_walk_through_a_grid/readme.md @@ -0,0 +1,60 @@ +3286\. Find a Safe Walk Through a Grid + +Medium + +You are given an `m x n` binary matrix `grid` and an integer `health`. + +You start on the upper-left corner `(0, 0)` and would like to get to the lower-right corner `(m - 1, n - 1)`. + +You can move up, down, left, or right from one cell to another adjacent cell as long as your health _remains_ **positive**. + +Cells `(i, j)` with `grid[i][j] = 1` are considered **unsafe** and reduce your health by 1. + +Return `true` if you can reach the final cell with a health value of 1 or more, and `false` otherwise. + +**Example 1:** + +**Input:** grid = [[0,1,0,0,0],[0,1,0,1,0],[0,0,0,1,0]], health = 1 + +**Output:** true + +**Explanation:** + +The final cell can be reached safely by walking along the gray cells below. + +![](https://assets.leetcode.com/uploads/2024/08/04/3868_examples_1drawio.png) + +**Example 2:** + +**Input:** grid = [[0,1,1,0,0,0],[1,0,1,0,0,0],[0,1,1,1,0,1],[0,0,1,0,1,0]], health = 3 + +**Output:** false + +**Explanation:** + +A minimum of 4 health points is needed to reach the final cell safely. + +![](https://assets.leetcode.com/uploads/2024/08/04/3868_examples_2drawio.png) + +**Example 3:** + +**Input:** grid = [[1,1,1],[1,0,1],[1,1,1]], health = 5 + +**Output:** true + +**Explanation:** + +The final cell can be reached safely by walking along the gray cells below. + +![](https://assets.leetcode.com/uploads/2024/08/04/3868_examples_3drawio.png) + +Any path that does not go through the cell `(1, 1)` is unsafe since your health will drop to 0 when reaching the final cell. + +**Constraints:** + +* `m == grid.length` +* `n == grid[i].length` +* `1 <= m, n <= 50` +* `2 <= m * n` +* `1 <= health <= m + n` +* `grid[i][j]` is either 0 or 1. \ No newline at end of file diff --git a/src/main/kotlin/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/Solution.kt b/src/main/kotlin/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/Solution.kt new file mode 100644 index 000000000..521803a28 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/Solution.kt @@ -0,0 +1,50 @@ +package g3201_3300.s3287_find_the_maximum_sequence_value_of_array + +// #Hard #Array #Dynamic_Programming #Bit_Manipulation +// #2024_09_17_Time_2893_ms_(33.33%)_Space_290.4_MB_(33.33%) + +import kotlin.math.max + +class Solution { + fun maxValue(nums: IntArray, k: Int): Int { + val n = nums.size + val left: Array>> = + Array>>(n) { Array>(k + 1) { mutableSetOf() } } + val right: Array>> = + Array>>(n) { Array>(k + 1) { mutableSetOf() } } + left[0][0].add(0) + left[0][1].add(nums[0]) + for (i in 1 until n - k) { + left[i][0].add(0) + for (j in 1..k) { + left[i][j].addAll(left[i - 1][j]) + for (v in left[i - 1][j - 1]) { + left[i][j].add(v or nums[i]) + } + } + } + right[n - 1][0].add(0) + right[n - 1][1].add(nums[n - 1]) + var result = 0 + if (k == 1) { + for (l in left[n - 2][k]) { + result = max(result, (l xor nums[n - 1])) + } + } + for (i in n - 2 downTo k) { + right[i][0].add(0) + for (j in 1..k) { + right[i][j].addAll(right[i + 1][j]) + for (v in right[i + 1][j - 1]) { + right[i][j].add(v or nums[i]) + } + } + for (l in left[i - 1][k]) { + for (r in right[i][k]) { + result = max(result, (l xor r)) + } + } + } + return result + } +} diff --git a/src/main/kotlin/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/readme.md b/src/main/kotlin/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/readme.md new file mode 100644 index 000000000..2d3f9813c --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/readme.md @@ -0,0 +1,37 @@ +3287\. Find the Maximum Sequence Value of Array + +Hard + +You are given an integer array `nums` and a **positive** integer `k`. + +The **value** of a sequence `seq` of size `2 * x` is defined as: + +* `(seq[0] OR seq[1] OR ... OR seq[x - 1]) XOR (seq[x] OR seq[x + 1] OR ... OR seq[2 * x - 1])`. + +Return the **maximum** **value** of any subsequence of `nums` having size `2 * k`. + +**Example 1:** + +**Input:** nums = [2,6,7], k = 1 + +**Output:** 5 + +**Explanation:** + +The subsequence `[2, 7]` has the maximum value of `2 XOR 7 = 5`. + +**Example 2:** + +**Input:** nums = [4,2,5,6,7], k = 2 + +**Output:** 2 + +**Explanation:** + +The subsequence `[4, 5, 6, 7]` has the maximum value of `(4 OR 5) XOR (6 OR 7) = 2`. + +**Constraints:** + +* `2 <= nums.length <= 400` +* 1 <= nums[i] < 27 +* `1 <= k <= nums.length / 2` \ No newline at end of file diff --git a/src/main/kotlin/g3201_3300/s3288_length_of_the_longest_increasing_path/Solution.kt b/src/main/kotlin/g3201_3300/s3288_length_of_the_longest_increasing_path/Solution.kt new file mode 100644 index 000000000..717f0ca16 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3288_length_of_the_longest_increasing_path/Solution.kt @@ -0,0 +1,71 @@ +package g3201_3300.s3288_length_of_the_longest_increasing_path + +// #Hard #Array #Sorting #Binary_Search #2024_09_17_Time_984_ms_(83.33%)_Space_147.1_MB_(16.67%) + +import java.util.ArrayList +import java.util.Comparator + +class Solution { + fun maxPathLength(coordinates: Array, k: Int): Int { + val upper: MutableList = ArrayList() + val lower: MutableList = ArrayList() + for (pair in coordinates) { + if (pair[0] > coordinates[k][0] && pair[1] > coordinates[k][1]) { + upper.add(pair) + } + if (pair[0] < coordinates[k][0] && pair[1] < coordinates[k][1]) { + lower.add(pair) + } + } + upper.sortWith( + Comparator { a: IntArray, b: IntArray -> + if (a[0] == b[0]) { + b[1] - a[1] + } else { + a[0] - b[0] + } + } + ) + lower.sortWith( + Comparator { a: IntArray, b: IntArray -> + if (a[0] == b[0]) { + b[1] - a[1] + } else { + a[0] - b[0] + } + } + ) + return longestIncreasingLength(upper) + longestIncreasingLength(lower) + 1 + } + + private fun longestIncreasingLength(array: List): Int { + val list: MutableList = ArrayList() + for (pair in array) { + val m = list.size + if (m == 0 || list[m - 1]!! < pair[1]) { + list.add(pair[1]) + } else { + val idx = binarySearch(list, pair[1]) + list[idx] = pair[1] + } + } + return list.size + } + + private fun binarySearch(list: List, target: Int): Int { + val n = list.size + var left = 0 + var right = n - 1 + while (left < right) { + val mid = (left + right) / 2 + if (list[mid] == target) { + return mid + } else if (list[mid]!! > target) { + right = mid + } else { + left = mid + 1 + } + } + return left + } +} diff --git a/src/main/kotlin/g3201_3300/s3288_length_of_the_longest_increasing_path/readme.md b/src/main/kotlin/g3201_3300/s3288_length_of_the_longest_increasing_path/readme.md new file mode 100644 index 000000000..bb3cc3f01 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3288_length_of_the_longest_increasing_path/readme.md @@ -0,0 +1,42 @@ +3288\. Length of the Longest Increasing Path + +Hard + +You are given a 2D array of integers `coordinates` of length `n` and an integer `k`, where `0 <= k < n`. + +coordinates[i] = [xi, yi] indicates the point (xi, yi) in a 2D plane. + +An **increasing path** of length `m` is defined as a list of points (x1, y1), (x2, y2), (x3, y3), ..., (xm, ym) such that: + +* xi < xi + 1 and yi < yi + 1 for all `i` where `1 <= i < m`. +* (xi, yi) is in the given coordinates for all `i` where `1 <= i <= m`. + +Return the **maximum** length of an **increasing path** that contains `coordinates[k]`. + +**Example 1:** + +**Input:** coordinates = [[3,1],[2,2],[4,1],[0,0],[5,3]], k = 1 + +**Output:** 3 + +**Explanation:** + +`(0, 0)`, `(2, 2)`, `(5, 3)` is the longest increasing path that contains `(2, 2)`. + +**Example 2:** + +**Input:** coordinates = [[2,1],[7,0],[5,6]], k = 2 + +**Output:** 2 + +**Explanation:** + +`(2, 1)`, `(5, 6)` is the longest increasing path that contains `(5, 6)`. + +**Constraints:** + +* 1 <= n == coordinates.length <= 105 +* `coordinates[i].length == 2` +* 0 <= coordinates[i][0], coordinates[i][1] <= 109 +* All elements in `coordinates` are **distinct**. +* `0 <= k <= n - 1` \ No newline at end of file diff --git a/src/main/kotlin/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/Solution.kt b/src/main/kotlin/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/Solution.kt new file mode 100644 index 000000000..8736b805e --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/Solution.kt @@ -0,0 +1,29 @@ +package g3201_3300.s3289_the_two_sneaky_numbers_of_digitville + +// #Easy #Array #Hash_Table #Math #2024_09_17_Time_223_ms_(68.97%)_Space_37.3_MB_(89.66%) + +import java.util.HashMap + +class Solution { + fun getSneakyNumbers(nums: IntArray): IntArray { + val countMap: MutableMap = HashMap() + // Populate the HashMap with the frequency of each number + for (num in nums) { + countMap.put(num, countMap.getOrDefault(num, 0) + 1) + } + // Array to store the result + val result = IntArray(2) + var index = 0 + // Find the numbers that appear exactly twice + for (entry in countMap.entries) { + if (entry.value == 2) { + result[index++] = entry.key + // Break if we have found both sneaky numbers + if (index == 2) { + break + } + } + } + return result + } +} diff --git a/src/main/kotlin/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/readme.md b/src/main/kotlin/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/readme.md new file mode 100644 index 000000000..1b9ef8720 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/readme.md @@ -0,0 +1,44 @@ +3289\. The Two Sneaky Numbers of Digitville + +Easy + +In the town of Digitville, there was a list of numbers called `nums` containing integers from `0` to `n - 1`. Each number was supposed to appear **exactly once** in the list, however, **two** mischievous numbers sneaked in an _additional time_, making the list longer than usual. + +As the town detective, your task is to find these two sneaky numbers. Return an array of size **two** containing the two numbers (in _any order_), so peace can return to Digitville. + +**Example 1:** + +**Input:** nums = [0,1,1,0] + +**Output:** [0,1] + +**Explanation:** + +The numbers 0 and 1 each appear twice in the array. + +**Example 2:** + +**Input:** nums = [0,3,2,1,3,2] + +**Output:** [2,3] + +**Explanation:** + +The numbers 2 and 3 each appear twice in the array. + +**Example 3:** + +**Input:** nums = [7,1,5,4,3,4,6,0,9,5,8,2] + +**Output:** [4,5] + +**Explanation:** + +The numbers 4 and 5 each appear twice in the array. + +**Constraints:** + +* `2 <= n <= 100` +* `nums.length == n + 2` +* `0 <= nums[i] < n` +* The input is generated such that `nums` contains **exactly** two repeated elements. \ No newline at end of file diff --git a/src/main/kotlin/g3201_3300/s3290_maximum_multiplication_score/Solution.kt b/src/main/kotlin/g3201_3300/s3290_maximum_multiplication_score/Solution.kt new file mode 100644 index 000000000..6ac55fb0e --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3290_maximum_multiplication_score/Solution.kt @@ -0,0 +1,18 @@ +package g3201_3300.s3290_maximum_multiplication_score + +// #Medium #Array #Dynamic_Programming #2024_09_17_Time_749_ms_(66.67%)_Space_71.3_MB_(75.00%) + +import kotlin.math.max + +class Solution { + fun maxScore(a: IntArray, b: IntArray): Long { + val dp = LongArray(4) + dp.fill((-1e11).toLong()) + for (bi in b) { + for (i in 3 downTo 0) { + dp[i] = max(dp[i], ((if (i > 0) dp[i - 1] else 0) + a[i].toLong() * bi)) + } + } + return dp[3] + } +} diff --git a/src/main/kotlin/g3201_3300/s3290_maximum_multiplication_score/readme.md b/src/main/kotlin/g3201_3300/s3290_maximum_multiplication_score/readme.md new file mode 100644 index 000000000..9f0367adc --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3290_maximum_multiplication_score/readme.md @@ -0,0 +1,33 @@ +3290\. Maximum Multiplication Score + +Medium + +You are given an integer array `a` of size 4 and another integer array `b` of size **at least** 4. + +You need to choose 4 indices i0, i1, i2, and i3 from the array `b` such that i0 < i1 < i2 < i3. Your score will be equal to the value a[0] * b[i0] + a[1] * b[i1] + a[2] * b[i2] + a[3] * b[i3]. + +Return the **maximum** score you can achieve. + +**Example 1:** + +**Input:** a = [3,2,5,6], b = [2,-6,4,-5,-3,2,-7] + +**Output:** 26 + +**Explanation:** + We can choose the indices 0, 1, 2, and 5. The score will be `3 * 2 + 2 * (-6) + 5 * 4 + 6 * 2 = 26`. + +**Example 2:** + +**Input:** a = [-1,4,5,-2], b = [-5,-1,-3,-2,-4] + +**Output:** \-1 + +**Explanation:** + We can choose the indices 0, 1, 3, and 4. The score will be `(-1) * (-5) + 4 * (-1) + 5 * (-2) + (-2) * (-4) = -1`. + +**Constraints:** + +* `a.length == 4` +* 4 <= b.length <= 105 +* -105 <= a[i], b[i] <= 105 \ No newline at end of file diff --git a/src/main/kotlin/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/Solution.kt b/src/main/kotlin/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/Solution.kt new file mode 100644 index 000000000..969b1487c --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/Solution.kt @@ -0,0 +1,51 @@ +package g3201_3300.s3291_minimum_number_of_valid_strings_to_form_target_i + +// #Medium #Array #String #Dynamic_Programming #Binary_Search #Trie #Segment_Tree #Hash_Function +// #String_Matching #Rolling_Hash #2024_09_17_Time_566_ms_(70.00%)_Space_50.2_MB_(80.00%) + +import kotlin.math.min + +class Solution { + fun minValidStrings(words: Array, target: String): Int { + val root = TrieNode() + for (word in words) { + insert(root, word) + } + val n = target.length + val dp = IntArray(n) + for (i in n - 1 downTo 0) { + dp[i] = Int.Companion.MAX_VALUE + var node = root + for (j in i until n) { + val idx = target[j].code - 'a'.code + if (node.children[idx] == null) { + break + } + if (j == n - 1) { + dp[i] = 1 + } else if (dp[j + 1] >= 0) { + dp[i] = min(dp[i], (1 + dp[j + 1])) + } + node = node.children[idx]!! + } + if (dp[i] == Int.Companion.MAX_VALUE) { + dp[i] = -1 + } + } + return dp[0] + } + + private fun insert(root: TrieNode, word: String) { + var node = root + for (c in word.toCharArray()) { + if (node.children[c.code - 'a'.code] == null) { + node.children[c.code - 'a'.code] = TrieNode() + } + node = node.children[c.code - 'a'.code]!! + } + } + + private class TrieNode { + var children: Array = arrayOfNulls(26) + } +} diff --git a/src/main/kotlin/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/readme.md b/src/main/kotlin/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/readme.md new file mode 100644 index 000000000..644afc0eb --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/readme.md @@ -0,0 +1,53 @@ +3291\. Minimum Number of Valid Strings to Form Target I + +Medium + +You are given an array of strings `words` and a string `target`. + +A string `x` is called **valid** if `x` is a prefix of **any** string in `words`. + +Return the **minimum** number of **valid** strings that can be _concatenated_ to form `target`. If it is **not** possible to form `target`, return `-1`. + +A prefix of a string is a substring that starts from the beginning of the string and extends to any point within it. + +**Example 1:** + +**Input:** words = ["abc","aaaaa","bcdef"], target = "aabcdabc" + +**Output:** 3 + +**Explanation:** + +The target string can be formed by concatenating: + +* Prefix of length 2 of `words[1]`, i.e. `"aa"`. +* Prefix of length 3 of `words[2]`, i.e. `"bcd"`. +* Prefix of length 3 of `words[0]`, i.e. `"abc"`. + +**Example 2:** + +**Input:** words = ["abababab","ab"], target = "ababaababa" + +**Output:** 2 + +**Explanation:** + +The target string can be formed by concatenating: + +* Prefix of length 5 of `words[0]`, i.e. `"ababa"`. +* Prefix of length 5 of `words[0]`, i.e. `"ababa"`. + +**Example 3:** + +**Input:** words = ["abcdef"], target = "xyz" + +**Output:** \-1 + +**Constraints:** + +* `1 <= words.length <= 100` +* 1 <= words[i].length <= 5 * 103 +* The input is generated such that sum(words[i].length) <= 105. +* `words[i]` consists only of lowercase English letters. +* 1 <= target.length <= 5 * 103 +* `target` consists only of lowercase English letters. \ No newline at end of file diff --git a/src/main/kotlin/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/Solution.kt b/src/main/kotlin/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/Solution.kt new file mode 100644 index 000000000..3177c7010 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/Solution.kt @@ -0,0 +1,66 @@ +package g3201_3300.s3292_minimum_number_of_valid_strings_to_form_target_ii + +// #Hard #Array #String #Dynamic_Programming #Binary_Search #Segment_Tree #Hash_Function +// #String_Matching #Rolling_Hash #2024_09_17_Time_674_ms_(50.00%)_Space_74.6_MB_(100.00%) + +import java.util.ArrayList +import kotlin.math.min + +class Solution { + fun minValidStrings(words: Array, target: String): Int { + val n = target.length + val dp = IntArray(n + 1) + dp.fill(Int.Companion.MAX_VALUE) + dp[0] = 0 + val matches: MutableList> = ArrayList>(n) + for (i in 0 until n) { + matches.add(ArrayList()) + } + val targetChars = target.toCharArray() + for (word in words) { + val wordChars = word.toCharArray() + val m = wordChars.size + val pi = IntArray(m) + var i1 = 1 + var j1 = 0 + while (i1 < m) { + while (j1 > 0 && wordChars[i1] != wordChars[j1]) { + j1 = pi[j1 - 1] + } + if (wordChars[i1] == wordChars[j1]) { + j1++ + } + pi[i1] = j1 + i1++ + } + var i = 0 + var j = 0 + while (i < n) { + while (j > 0 && targetChars[i] != wordChars[j]) { + j = pi[j - 1] + } + if (targetChars[i] == wordChars[j]) { + j++ + } + if (j > 0) { + matches[i - j + 1].add(j) + if (j == m) { + j = pi[j - 1] + } + } + i++ + } + } + for (i in 0 until n) { + if (dp[i] == Int.Companion.MAX_VALUE) { + continue + } + for (len in matches[i]) { + if (i + len <= n) { + dp[i + len] = min(dp[i + len], (dp[i] + 1)) + } + } + } + return if (dp[n] == Int.Companion.MAX_VALUE) -1 else dp[n] + } +} diff --git a/src/main/kotlin/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/readme.md b/src/main/kotlin/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/readme.md new file mode 100644 index 000000000..e8cfa8084 --- /dev/null +++ b/src/main/kotlin/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/readme.md @@ -0,0 +1,53 @@ +3292\. Minimum Number of Valid Strings to Form Target II + +Hard + +You are given an array of strings `words` and a string `target`. + +A string `x` is called **valid** if `x` is a prefix of **any** string in `words`. + +Return the **minimum** number of **valid** strings that can be _concatenated_ to form `target`. If it is **not** possible to form `target`, return `-1`. + +A prefix of a string is a substring that starts from the beginning of the string and extends to any point within it. + +**Example 1:** + +**Input:** words = ["abc","aaaaa","bcdef"], target = "aabcdabc" + +**Output:** 3 + +**Explanation:** + +The target string can be formed by concatenating: + +* Prefix of length 2 of `words[1]`, i.e. `"aa"`. +* Prefix of length 3 of `words[2]`, i.e. `"bcd"`. +* Prefix of length 3 of `words[0]`, i.e. `"abc"`. + +**Example 2:** + +**Input:** words = ["abababab","ab"], target = "ababaababa" + +**Output:** 2 + +**Explanation:** + +The target string can be formed by concatenating: + +* Prefix of length 5 of `words[0]`, i.e. `"ababa"`. +* Prefix of length 5 of `words[0]`, i.e. `"ababa"`. + +**Example 3:** + +**Input:** words = ["abcdef"], target = "xyz" + +**Output:** \-1 + +**Constraints:** + +* `1 <= words.length <= 100` +* 1 <= words[i].length <= 5 * 104 +* The input is generated such that sum(words[i].length) <= 105. +* `words[i]` consists only of lowercase English letters. +* 1 <= target.length <= 5 * 104 +* `target` consists only of lowercase English letters. \ No newline at end of file diff --git a/src/test/kotlin/g3201_3300/s3285_find_indices_of_stable_mountains/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3285_find_indices_of_stable_mountains/SolutionTest.kt new file mode 100644 index 000000000..5b8873dce --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3285_find_indices_of_stable_mountains/SolutionTest.kt @@ -0,0 +1,31 @@ +package g3201_3300.s3285_find_indices_of_stable_mountains + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun stableMountains() { + assertThat>( + Solution().stableMountains(intArrayOf(1, 2, 3, 4, 5), 2), + equalTo>(listOf(3, 4)) + ) + } + + @Test + fun stableMountains2() { + assertThat>( + Solution().stableMountains(intArrayOf(10, 1, 10, 1, 10), 3), + equalTo>(listOf(1, 3)) + ) + } + + @Test + fun stableMountains3() { + assertThat>( + Solution().stableMountains(intArrayOf(10, 1, 10, 1, 10), 10), + equalTo>(listOf()) + ) + } +} diff --git a/src/test/kotlin/g3201_3300/s3286_find_a_safe_walk_through_a_grid/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3286_find_a_safe_walk_through_a_grid/SolutionTest.kt new file mode 100644 index 000000000..901602fa3 --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3286_find_a_safe_walk_through_a_grid/SolutionTest.kt @@ -0,0 +1,61 @@ +package g3201_3300.s3286_find_a_safe_walk_through_a_grid + +import com_github_leetcode.ArrayUtils.getLists +import org.hamcrest.CoreMatchers +import org.hamcrest.MatcherAssert +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun findSafeWalk() { + MatcherAssert.assertThat( + Solution() + .findSafeWalk( + getLists( + arrayOf( + intArrayOf(0, 1, 0, 0, 0), intArrayOf(0, 1, 0, 1, 0), intArrayOf(0, 0, 0, 1, 0) + ) + ), + 1 + ), + CoreMatchers.equalTo(true) + ) + } + + @Test + fun findSafeWalk2() { + MatcherAssert.assertThat( + Solution() + .findSafeWalk( + getLists( + arrayOf( + intArrayOf(0, 1, 1, 0, 0, 0), + intArrayOf(1, 0, 1, 0, 0, 0), + intArrayOf(0, 1, 1, 1, 0, 1), + intArrayOf(0, 0, 1, 0, 1, 0) + ) + ), + 3 + ), + CoreMatchers.equalTo(false) + ) + } + + @Test + fun findSafeWalk3() { + MatcherAssert.assertThat( + Solution() + .findSafeWalk( + getLists( + arrayOf( + intArrayOf(1, 1, 1), + intArrayOf(1, 0, 1), + intArrayOf(1, 1, 1) + ) + ), + 5 + ), + CoreMatchers.equalTo(true) + ) + } +} diff --git a/src/test/kotlin/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/SolutionTest.kt new file mode 100644 index 000000000..ad6e34be7 --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/SolutionTest.kt @@ -0,0 +1,17 @@ +package g3201_3300.s3287_find_the_maximum_sequence_value_of_array + +import org.hamcrest.CoreMatchers +import org.hamcrest.MatcherAssert +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun maxValue() { + MatcherAssert.assertThat(Solution().maxValue(intArrayOf(2, 6, 7), 1), CoreMatchers.equalTo(5)) + } + + @Test + fun maxValue2() { + MatcherAssert.assertThat(Solution().maxValue(intArrayOf(4, 2, 5, 6, 7), 2), CoreMatchers.equalTo(2)) + } +} diff --git a/src/test/kotlin/g3201_3300/s3288_length_of_the_longest_increasing_path/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3288_length_of_the_longest_increasing_path/SolutionTest.kt new file mode 100644 index 000000000..f4138e6f9 --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3288_length_of_the_longest_increasing_path/SolutionTest.kt @@ -0,0 +1,77 @@ +package g3201_3300.s3288_length_of_the_longest_increasing_path + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun maxPathLength() { + assertThat( + Solution() + .maxPathLength( + arrayOf( + intArrayOf(3, 1), + intArrayOf(2, 2), + intArrayOf(4, 1), + intArrayOf(0, 0), + intArrayOf(5, 3) + ), + 1 + ), + equalTo(3) + ) + } + + @Test + fun maxPathLength2() { + assertThat( + Solution().maxPathLength(arrayOf(intArrayOf(2, 1), intArrayOf(7, 0), intArrayOf(5, 6)), 2), + equalTo(2) + ) + } + + @Test + fun maxPathLength3() { + assertThat( + Solution().maxPathLength(arrayOf(intArrayOf(0, 3), intArrayOf(8, 5), intArrayOf(6, 8)), 0), + equalTo(2) + ) + } + + @Test + fun maxPathLength4() { + assertThat( + Solution().maxPathLength( + arrayOf( + intArrayOf(8, 8), + intArrayOf(7, 0), + intArrayOf(5, 6), + intArrayOf(9, 1) + ), + 0 + ), + equalTo(2) + ) + } + + @Test + fun maxPathLength5() { + assertThat( + Solution() + .maxPathLength( + arrayOf( + intArrayOf(1, 1), + intArrayOf(0, 1), + intArrayOf(5, 4), + intArrayOf(3, 3), + intArrayOf(2, 0), + intArrayOf(1, 4), + intArrayOf(6, 8) + ), + 6 + ), + equalTo(4) + ) + } +} diff --git a/src/test/kotlin/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/SolutionTest.kt new file mode 100644 index 000000000..9f256c9c9 --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/SolutionTest.kt @@ -0,0 +1,30 @@ +package g3201_3300.s3289_the_two_sneaky_numbers_of_digitville + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun getSneakyNumbers() { + assertThat( + Solution().getSneakyNumbers(intArrayOf(0, 1, 1, 0)), equalTo(intArrayOf(0, 1)) + ) + } + + @Test + fun getSneakyNumbers2() { + assertThat( + Solution().getSneakyNumbers(intArrayOf(0, 3, 2, 1, 3, 2)), + equalTo(intArrayOf(2, 3)) + ) + } + + @Test + fun getSneakyNumbers3() { + assertThat( + Solution().getSneakyNumbers(intArrayOf(7, 1, 5, 4, 3, 4, 6, 0, 9, 5, 8, 2)), + equalTo(intArrayOf(4, 5)) + ) + } +} diff --git a/src/test/kotlin/g3201_3300/s3290_maximum_multiplication_score/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3290_maximum_multiplication_score/SolutionTest.kt new file mode 100644 index 000000000..bb71feeff --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3290_maximum_multiplication_score/SolutionTest.kt @@ -0,0 +1,24 @@ +package g3201_3300.s3290_maximum_multiplication_score + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun maxScore() { + assertThat( + Solution() + .maxScore(intArrayOf(3, 2, 5, 6), intArrayOf(2, -6, 4, -5, -3, 2, -7)), + equalTo(26L) + ) + } + + @Test + fun maxScore2() { + assertThat( + Solution().maxScore(intArrayOf(-1, 4, 5, -2), intArrayOf(-5, -1, -3, -2, -4)), + equalTo(-1L) + ) + } +} diff --git a/src/test/kotlin/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/SolutionTest.kt new file mode 100644 index 000000000..8073cbbb0 --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/SolutionTest.kt @@ -0,0 +1,31 @@ +package g3201_3300.s3291_minimum_number_of_valid_strings_to_form_target_i + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun minValidStrings() { + assertThat( + Solution().minValidStrings(arrayOf("abc", "aaaaa", "bcdef"), "aabcdabc"), + equalTo(3) + ) + } + + @Test + fun minValidStrings2() { + assertThat( + Solution().minValidStrings(arrayOf("abababab", "ab"), "ababaababa"), + equalTo(2) + ) + } + + @Test + fun minValidStrings3() { + assertThat( + Solution().minValidStrings(arrayOf("abcdef"), "xyz"), + equalTo(-1) + ) + } +} diff --git a/src/test/kotlin/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/SolutionTest.kt b/src/test/kotlin/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/SolutionTest.kt new file mode 100644 index 000000000..1d38683b6 --- /dev/null +++ b/src/test/kotlin/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/SolutionTest.kt @@ -0,0 +1,31 @@ +package g3201_3300.s3292_minimum_number_of_valid_strings_to_form_target_ii + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun minValidStrings() { + assertThat( + Solution().minValidStrings(arrayOf("abc", "aaaaa", "bcdef"), "aabcdabc"), + equalTo(3) + ) + } + + @Test + fun minValidStrings2() { + assertThat( + Solution().minValidStrings(arrayOf("abababab", "ab"), "ababaababa"), + equalTo(2) + ) + } + + @Test + fun minValidStrings3() { + assertThat( + Solution().minValidStrings(arrayOf("abcdef"), "xyz"), + equalTo(-1) + ) + } +}