diff --git a/src/main/java/g3201_3300/s3285_find_indices_of_stable_mountains/Solution.java b/src/main/java/g3201_3300/s3285_find_indices_of_stable_mountains/Solution.java new file mode 100644 index 000000000..ff0e8b4e0 --- /dev/null +++ b/src/main/java/g3201_3300/s3285_find_indices_of_stable_mountains/Solution.java @@ -0,0 +1,19 @@ +package g3201_3300.s3285_find_indices_of_stable_mountains; + +// #Easy #Array #2024_09_15_Time_1_ms_(100.00%)_Space_44.5_MB_(100.00%) + +import java.util.ArrayList; +import java.util.List; + +public class Solution { + public List stableMountains(int[] height, int threshold) { + int n = height.length; + List list = new ArrayList<>(); + for (int i = 0; i < n - 1; i++) { + if (height[i] > threshold) { + list.add(i + 1); + } + } + return list; + } +} diff --git a/src/main/java/g3201_3300/s3285_find_indices_of_stable_mountains/readme.md b/src/main/java/g3201_3300/s3285_find_indices_of_stable_mountains/readme.md new file mode 100644 index 000000000..6f8a52271 --- /dev/null +++ b/src/main/java/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/java/g3201_3300/s3286_find_a_safe_walk_through_a_grid/Solution.java b/src/main/java/g3201_3300/s3286_find_a_safe_walk_through_a_grid/Solution.java new file mode 100644 index 000000000..8785b20a9 --- /dev/null +++ b/src/main/java/g3201_3300/s3286_find_a_safe_walk_through_a_grid/Solution.java @@ -0,0 +1,50 @@ +package g3201_3300.s3286_find_a_safe_walk_through_a_grid; + +// #Medium #Array #Matrix #Heap_Priority_Queue #Graph #Shortest_Path #Breadth_First_Search +// #2024_09_15_Time_90_ms_(100.00%)_Space_46.6_MB_(100.00%) + +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import java.util.Queue; + +public class Solution { + public boolean findSafeWalk(List> grid, int health) { + int n = grid.size(); + int m = grid.get(0).size(); + int[] dr = new int[] {0, 0, 1, -1}; + int[] dc = new int[] {1, -1, 0, 0}; + boolean[][][] visited = new boolean[n][m][health + 1]; + Queue bfs = new LinkedList<>(); + bfs.add(new int[] {0, 0, health - grid.get(0).get(0)}); + visited[0][0][health - grid.get(0).get(0)] = true; + while (!bfs.isEmpty()) { + int size = bfs.size(); + while (size-- > 0) { + int[] currNode = bfs.poll(); + int r = Objects.requireNonNull(currNode)[0]; + int c = currNode[1]; + int h = currNode[2]; + if (r == n - 1 && c == m - 1 && h > 0) { + return true; + } + for (int k = 0; k < 4; k++) { + int nr = r + dr[k]; + int nc = c + dc[k]; + if (isValidMove(nr, nc, n, m)) { + int nh = h - grid.get(nr).get(nc); + if (nh >= 0 && !visited[nr][nc][nh]) { + visited[nr][nc][nh] = true; + bfs.add(new int[] {nr, nc, nh}); + } + } + } + } + } + return false; + } + + private boolean isValidMove(int r, int c, int n, int m) { + return r >= 0 && c >= 0 && r < n && c < m; + } +} diff --git a/src/main/java/g3201_3300/s3286_find_a_safe_walk_through_a_grid/readme.md b/src/main/java/g3201_3300/s3286_find_a_safe_walk_through_a_grid/readme.md new file mode 100644 index 000000000..331587234 --- /dev/null +++ b/src/main/java/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/java/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/Solution.java b/src/main/java/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/Solution.java new file mode 100644 index 000000000..736f49a8b --- /dev/null +++ b/src/main/java/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/Solution.java @@ -0,0 +1,56 @@ +package g3201_3300.s3287_find_the_maximum_sequence_value_of_array; + +// #Hard #Array #Dynamic_Programming #Bit_Manipulation +// #2024_09_15_Time_1140_ms_(100.00%)_Space_285.4_MB_(100.00%) + +import java.util.HashSet; +import java.util.Set; + +@SuppressWarnings("unchecked") +public class Solution { + public int maxValue(int[] nums, int k) { + int n = nums.length; + Set[][] left = new Set[n][k + 1]; + Set[][] right = new Set[n][k + 1]; + for (int i = 0; i < n; i++) { + for (int j = 0; j <= k; j++) { + left[i][j] = new HashSet<>(); + right[i][j] = new HashSet<>(); + } + } + left[0][0].add(0); + left[0][1].add(nums[0]); + for (int i = 1; i < n - k; i++) { + left[i][0].add(0); + for (int j = 1; j <= k; j++) { + left[i][j].addAll(left[i - 1][j]); + for (int v : left[i - 1][j - 1]) { + left[i][j].add(v | nums[i]); + } + } + } + right[n - 1][0].add(0); + right[n - 1][1].add(nums[n - 1]); + int result = 0; + if (k == 1) { + for (int l : left[n - 2][k]) { + result = Math.max(result, l ^ nums[n - 1]); + } + } + for (int i = n - 2; i >= k; i--) { + right[i][0].add(0); + for (int j = 1; j <= k; j++) { + right[i][j].addAll(right[i + 1][j]); + for (int v : right[i + 1][j - 1]) { + right[i][j].add(v | nums[i]); + } + } + for (int l : left[i - 1][k]) { + for (int r : right[i][k]) { + result = Math.max(result, l ^ r); + } + } + } + return result; + } +} diff --git a/src/main/java/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/readme.md b/src/main/java/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/readme.md new file mode 100644 index 000000000..2d3f9813c --- /dev/null +++ b/src/main/java/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/java/g3201_3300/s3288_length_of_the_longest_increasing_path/Solution.java b/src/main/java/g3201_3300/s3288_length_of_the_longest_increasing_path/Solution.java new file mode 100644 index 000000000..f6ffcb1f4 --- /dev/null +++ b/src/main/java/g3201_3300/s3288_length_of_the_longest_increasing_path/Solution.java @@ -0,0 +1,69 @@ +package g3201_3300.s3288_length_of_the_longest_increasing_path; + +// #Hard #Array #Sorting #Binary_Search #2024_09_15_Time_34_ms_(100.00%)_Space_106.2_MB_(50.00%) + +import java.util.ArrayList; +import java.util.List; + +public class Solution { + public int maxPathLength(int[][] coordinates, int k) { + List upper = new ArrayList<>(); + List lower = new ArrayList<>(); + for (int[] pair : 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.sort( + (a, b) -> { + if (a[0] == b[0]) { + return b[1] - a[1]; + } else { + return a[0] - b[0]; + } + }); + lower.sort( + (a, b) -> { + if (a[0] == b[0]) { + return b[1] - a[1]; + } else { + return a[0] - b[0]; + } + }); + return longestIncreasingLength(upper) + longestIncreasingLength(lower) + 1; + } + + private int longestIncreasingLength(List array) { + List list = new ArrayList<>(); + for (int[] pair : array) { + int m = list.size(); + if (m == 0 || list.get(m - 1) < pair[1]) { + list.add(pair[1]); + } else { + int idx = binarySearch(list, pair[1]); + list.set(idx, pair[1]); + } + } + return list.size(); + } + + private int binarySearch(List list, int target) { + int n = list.size(); + int left = 0; + int right = n - 1; + while (left < right) { + int mid = (left + right) / 2; + if (list.get(mid) == target) { + return mid; + } else if (list.get(mid) > target) { + right = mid; + } else { + left = mid + 1; + } + } + return left; + } +} diff --git a/src/main/java/g3201_3300/s3288_length_of_the_longest_increasing_path/readme.md b/src/main/java/g3201_3300/s3288_length_of_the_longest_increasing_path/readme.md new file mode 100644 index 000000000..bb3cc3f01 --- /dev/null +++ b/src/main/java/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/java/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/Solution.java b/src/main/java/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/Solution.java new file mode 100644 index 000000000..3ac97d36b --- /dev/null +++ b/src/main/java/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/Solution.java @@ -0,0 +1,30 @@ +package g3201_3300.s3289_the_two_sneaky_numbers_of_digitville; + +// #Easy #Array #Hash_Table #Math #2024_09_16_Time_3_ms_(100.00%)_Space_45_MB_(100.00%) + +import java.util.HashMap; +import java.util.Map; + +public class Solution { + public int[] getSneakyNumbers(int[] nums) { + Map countMap = new HashMap<>(); + // Populate the HashMap with the frequency of each number + for (int num : nums) { + countMap.put(num, countMap.getOrDefault(num, 0) + 1); + } + // Array to store the result + int[] result = new int[2]; + int index = 0; + // Find the numbers that appear exactly twice + for (Map.Entry entry : countMap.entrySet()) { + if (entry.getValue() == 2) { + result[index++] = entry.getKey(); + // Break if we have found both sneaky numbers + if (index == 2) { + break; + } + } + } + return result; + } +} diff --git a/src/main/java/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/readme.md b/src/main/java/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/readme.md new file mode 100644 index 000000000..1b9ef8720 --- /dev/null +++ b/src/main/java/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/java/g3201_3300/s3290_maximum_multiplication_score/Solution.java b/src/main/java/g3201_3300/s3290_maximum_multiplication_score/Solution.java new file mode 100644 index 000000000..caf591a34 --- /dev/null +++ b/src/main/java/g3201_3300/s3290_maximum_multiplication_score/Solution.java @@ -0,0 +1,18 @@ +package g3201_3300.s3290_maximum_multiplication_score; + +// #Medium #Array #Dynamic_Programming #2024_09_16_Time_8_ms_(100.00%)_Space_62.5_MB_(100.00%) + +import java.util.Arrays; + +public class Solution { + public long maxScore(int[] a, int[] b) { + long[] dp = new long[4]; + Arrays.fill(dp, (long) -1e11); + for (int bi : b) { + for (int i = 3; i >= 0; i--) { + dp[i] = Math.max(dp[i], (i > 0 ? dp[i - 1] : 0) + (long) a[i] * bi); + } + } + return dp[3]; + } +} diff --git a/src/main/java/g3201_3300/s3290_maximum_multiplication_score/readme.md b/src/main/java/g3201_3300/s3290_maximum_multiplication_score/readme.md new file mode 100644 index 000000000..9f0367adc --- /dev/null +++ b/src/main/java/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/java/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/Solution.java b/src/main/java/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/Solution.java new file mode 100644 index 000000000..331e3bfcf --- /dev/null +++ b/src/main/java/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/Solution.java @@ -0,0 +1,49 @@ +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_16_Time_263_ms_(60.00%)_Space_56.9_MB_(20.00%) + +public class Solution { + public int minValidStrings(String[] words, String target) { + TrieNode root = new TrieNode(); + for (String word : words) { + insert(root, word); + } + int n = target.length(); + int[] dp = new int[n]; + for (int i = n - 1; i >= 0; i--) { + dp[i] = Integer.MAX_VALUE; + TrieNode node = root; + for (int j = i; j < n; j++) { + int idx = target.charAt(j) - 'a'; + if (node.children[idx] == null) { + break; + } + if (j == n - 1) { + dp[i] = 1; + } else if (dp[j + 1] >= 0) { + dp[i] = Math.min(dp[i], 1 + dp[j + 1]); + } + node = node.children[idx]; + } + if (dp[i] == Integer.MAX_VALUE) { + dp[i] = -1; + } + } + return dp[0]; + } + + private void insert(TrieNode root, String word) { + TrieNode node = root; + for (char c : word.toCharArray()) { + if (node.children[c - 'a'] == null) { + node.children[c - 'a'] = new TrieNode(); + } + node = node.children[c - 'a']; + } + } + + private static class TrieNode { + TrieNode[] children = new TrieNode[26]; + } +} diff --git a/src/main/java/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/readme.md b/src/main/java/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/java/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/java/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/Solution.java b/src/main/java/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/Solution.java new file mode 100644 index 000000000..796e13c3a --- /dev/null +++ b/src/main/java/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/Solution.java @@ -0,0 +1,67 @@ +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_16_Time_103_ms_(100.00%)_Space_94.7_MB_(100.00%) + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Solution { + public int minValidStrings(String[] words, String target) { + int n = target.length(); + int[] dp = new int[n + 1]; + Arrays.fill(dp, Integer.MAX_VALUE); + dp[0] = 0; + List> matches = new ArrayList<>(n); + for (int i = 0; i < n; i++) { + matches.add(new ArrayList<>()); + } + char[] targetChars = target.toCharArray(); + for (String word : words) { + char[] wordChars = word.toCharArray(); + int m = wordChars.length; + int[] pi = new int[m]; + int i1 = 1; + int 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++; + } + int i = 0; + int 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.get(i - j + 1).add(j); + if (j == m) { + j = pi[j - 1]; + } + } + i++; + } + } + for (int i = 0; i < n; i++) { + if (dp[i] == Integer.MAX_VALUE) { + continue; + } + for (int len : matches.get(i)) { + if (i + len <= n) { + dp[i + len] = Math.min(dp[i + len], dp[i] + 1); + } + } + } + return dp[n] == Integer.MAX_VALUE ? -1 : dp[n]; + } +} diff --git a/src/main/java/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/readme.md b/src/main/java/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/java/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/java/g3201_3300/s3285_find_indices_of_stable_mountains/SolutionTest.java b/src/test/java/g3201_3300/s3285_find_indices_of_stable_mountains/SolutionTest.java new file mode 100644 index 000000000..c4346dde3 --- /dev/null +++ b/src/test/java/g3201_3300/s3285_find_indices_of_stable_mountains/SolutionTest.java @@ -0,0 +1,30 @@ +package g3201_3300.s3285_find_indices_of_stable_mountains; + +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 stableMountains() { + assertThat( + new Solution().stableMountains(new int[] {1, 2, 3, 4, 5}, 2), + equalTo(List.of(3, 4))); + } + + @Test + void stableMountains2() { + assertThat( + new Solution().stableMountains(new int[] {10, 1, 10, 1, 10}, 3), + equalTo(List.of(1, 3))); + } + + @Test + void stableMountains3() { + assertThat( + new Solution().stableMountains(new int[] {10, 1, 10, 1, 10}, 10), + equalTo(List.of())); + } +} diff --git a/src/test/java/g3201_3300/s3286_find_a_safe_walk_through_a_grid/SolutionTest.java b/src/test/java/g3201_3300/s3286_find_a_safe_walk_through_a_grid/SolutionTest.java new file mode 100644 index 000000000..e4ad74875 --- /dev/null +++ b/src/test/java/g3201_3300/s3286_find_a_safe_walk_through_a_grid/SolutionTest.java @@ -0,0 +1,48 @@ +package g3201_3300.s3286_find_a_safe_walk_through_a_grid; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import com_github_leetcode.ArrayUtils; +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void findSafeWalk() { + assertThat( + new Solution() + .findSafeWalk( + ArrayUtils.getLists( + new int[][] { + {0, 1, 0, 0, 0}, {0, 1, 0, 1, 0}, {0, 0, 0, 1, 0} + }), + 1), + equalTo(true)); + } + + @Test + void findSafeWalk2() { + assertThat( + new Solution() + .findSafeWalk( + ArrayUtils.getLists( + new int[][] { + {0, 1, 1, 0, 0, 0}, + {1, 0, 1, 0, 0, 0}, + {0, 1, 1, 1, 0, 1}, + {0, 0, 1, 0, 1, 0} + }), + 3), + equalTo(false)); + } + + @Test + void findSafeWalk3() { + assertThat( + new Solution() + .findSafeWalk( + ArrayUtils.getLists(new int[][] {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}), + 5), + equalTo(true)); + } +} diff --git a/src/test/java/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/SolutionTest.java b/src/test/java/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/SolutionTest.java new file mode 100644 index 000000000..abaf67730 --- /dev/null +++ b/src/test/java/g3201_3300/s3287_find_the_maximum_sequence_value_of_array/SolutionTest.java @@ -0,0 +1,18 @@ +package g3201_3300.s3287_find_the_maximum_sequence_value_of_array; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxValue() { + assertThat(new Solution().maxValue(new int[] {2, 6, 7}, 1), equalTo(5)); + } + + @Test + void maxValue2() { + assertThat(new Solution().maxValue(new int[] {4, 2, 5, 6, 7}, 2), equalTo(2)); + } +} diff --git a/src/test/java/g3201_3300/s3288_length_of_the_longest_increasing_path/SolutionTest.java b/src/test/java/g3201_3300/s3288_length_of_the_longest_increasing_path/SolutionTest.java new file mode 100644 index 000000000..4d23f58e3 --- /dev/null +++ b/src/test/java/g3201_3300/s3288_length_of_the_longest_increasing_path/SolutionTest.java @@ -0,0 +1,47 @@ +package g3201_3300.s3288_length_of_the_longest_increasing_path; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxPathLength() { + assertThat( + new Solution() + .maxPathLength(new int[][] {{3, 1}, {2, 2}, {4, 1}, {0, 0}, {5, 3}}, 1), + equalTo(3)); + } + + @Test + void maxPathLength2() { + assertThat( + new Solution().maxPathLength(new int[][] {{2, 1}, {7, 0}, {5, 6}}, 2), equalTo(2)); + } + + @Test + void maxPathLength3() { + assertThat( + new Solution().maxPathLength(new int[][] {{0, 3}, {8, 5}, {6, 8}}, 0), equalTo(2)); + } + + @Test + void maxPathLength4() { + assertThat( + new Solution().maxPathLength(new int[][] {{8, 8}, {7, 0}, {5, 6}, {9, 1}}, 0), + equalTo(2)); + } + + @Test + void maxPathLength5() { + assertThat( + new Solution() + .maxPathLength( + new int[][] { + {1, 1}, {0, 1}, {5, 4}, {3, 3}, {2, 0}, {1, 4}, {6, 8} + }, + 6), + equalTo(4)); + } +} diff --git a/src/test/java/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/SolutionTest.java b/src/test/java/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/SolutionTest.java new file mode 100644 index 000000000..61d284fa8 --- /dev/null +++ b/src/test/java/g3201_3300/s3289_the_two_sneaky_numbers_of_digitville/SolutionTest.java @@ -0,0 +1,28 @@ +package g3201_3300.s3289_the_two_sneaky_numbers_of_digitville; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void getSneakyNumbers() { + assertThat( + new Solution().getSneakyNumbers(new int[] {0, 1, 1, 0}), equalTo(new int[] {0, 1})); + } + + @Test + void getSneakyNumbers2() { + assertThat( + new Solution().getSneakyNumbers(new int[] {0, 3, 2, 1, 3, 2}), + equalTo(new int[] {2, 3})); + } + + @Test + void getSneakyNumbers3() { + assertThat( + new Solution().getSneakyNumbers(new int[] {7, 1, 5, 4, 3, 4, 6, 0, 9, 5, 8, 2}), + equalTo(new int[] {4, 5})); + } +} diff --git a/src/test/java/g3201_3300/s3290_maximum_multiplication_score/SolutionTest.java b/src/test/java/g3201_3300/s3290_maximum_multiplication_score/SolutionTest.java new file mode 100644 index 000000000..7fa53cd95 --- /dev/null +++ b/src/test/java/g3201_3300/s3290_maximum_multiplication_score/SolutionTest.java @@ -0,0 +1,23 @@ +package g3201_3300.s3290_maximum_multiplication_score; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxScore() { + assertThat( + new Solution() + .maxScore(new int[] {3, 2, 5, 6}, new int[] {2, -6, 4, -5, -3, 2, -7}), + equalTo(26L)); + } + + @Test + void maxScore2() { + assertThat( + new Solution().maxScore(new int[] {-1, 4, 5, -2}, new int[] {-5, -1, -3, -2, -4}), + equalTo(-1L)); + } +} diff --git a/src/test/java/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/SolutionTest.java b/src/test/java/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/SolutionTest.java new file mode 100644 index 000000000..3ba7d773a --- /dev/null +++ b/src/test/java/g3201_3300/s3291_minimum_number_of_valid_strings_to_form_target_i/SolutionTest.java @@ -0,0 +1,27 @@ +package g3201_3300.s3291_minimum_number_of_valid_strings_to_form_target_i; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void minValidStrings() { + assertThat( + new Solution().minValidStrings(new String[] {"abc", "aaaaa", "bcdef"}, "aabcdabc"), + equalTo(3)); + } + + @Test + void minValidStrings2() { + assertThat( + new Solution().minValidStrings(new String[] {"abababab", "ab"}, "ababaababa"), + equalTo(2)); + } + + @Test + void minValidStrings3() { + assertThat(new Solution().minValidStrings(new String[] {"abcdef"}, "xyz"), equalTo(-1)); + } +} diff --git a/src/test/java/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/SolutionTest.java b/src/test/java/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/SolutionTest.java new file mode 100644 index 000000000..dc2c459bd --- /dev/null +++ b/src/test/java/g3201_3300/s3292_minimum_number_of_valid_strings_to_form_target_ii/SolutionTest.java @@ -0,0 +1,27 @@ +package g3201_3300.s3292_minimum_number_of_valid_strings_to_form_target_ii; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void minValidStrings() { + assertThat( + new Solution().minValidStrings(new String[] {"abc", "aaaaa", "bcdef"}, "aabcdabc"), + equalTo(3)); + } + + @Test + void minValidStrings2() { + assertThat( + new Solution().minValidStrings(new String[] {"abababab", "ab"}, "ababaababa"), + equalTo(2)); + } + + @Test + void minValidStrings3() { + assertThat(new Solution().minValidStrings(new String[] {"abcdef"}, "xyz"), equalTo(-1)); + } +}