diff --git a/solution/3200-3299/3292.Minimum Number of Valid Strings to Form Target II/README.md b/solution/3200-3299/3292.Minimum Number of Valid Strings to Form Target II/README.md index 25412bb7224d0..1355c3c47e533 100644 --- a/solution/3200-3299/3292.Minimum Number of Valid Strings to Form Target II/README.md +++ b/solution/3200-3299/3292.Minimum Number of Valid Strings to Form Target II/README.md @@ -95,7 +95,25 @@ tags: -### 方法一 +### 方法一:字符串哈希 + 二分查找 + 贪心 + +由于本题数据规模较大,使用“字典树 + 记忆化搜索”的方法将会超时,我们需要寻找一种更高效的解法。 + +考虑从字符串 $\textit{target}$ 的第 $i$ 个字符开始,最远能够匹配的字符串长度,假设为 $\textit{dist}$,那么对于任意 $j \in [i, i + \textit{dist}-1]$,我们都能够在 $\textit{words}$ 中找到一个字符串,使得 $\textit{target}[i..j]$ 是这个字符串的前缀。这存在着单调性,我们可以使用二分查找来确定 $\textit{dist}$。 + +具体地,我们首先预处理出 $\textit{words}$ 中所有字符串的每个前缀的哈希值,按照前缀长度分组存储在 $\textit{s}$ 数组中。另外,将 $\textit{target}$ 的哈希值也预处理出来,存储在 $\textit{hashing}$ 中,便于我们查询任意 $\textit{target}[l..r]$ 的哈希值。 + +接下来,我们设计一个函数 $\textit{f}(i)$,表示从字符串 $\textit{target}$ 的第 $i$ 个字符开始,最远能够匹配的字符串长度。我们可以通过二分查找的方式确定 $\textit{f}(i)$。 + +定义二分查找的左边界 $l = 0$,右边界 $r = \min(n - i, m)$,其中 $n$ 是字符串 $\textit{target}$ 的长度,而 $m$ 是 $\textit{words}$ 中字符串的最大长度。在二分查找的过程中,我们需要判断 $\textit{target}[i..i+\textit{mid}-1]$ 是否是 $\textit{s}[\textit{mid}]$ 中的某个哈希值,如果是,则将左边界 $l$ 更新为 $\textit{mid}$,否则将右边界 $r$ 更新为 $\textit{mid}-1$。二分结束后,返回 $l$ 即可。 + +算出 $\textit{f}(i)$ 后,问题就转化为了一个经典的贪心问题,我们从 $i = 0$ 开始,对于每个位置 $i$,最远可以移动到的位置为 $i + \textit{f}(i)$,求最少需要多少次移动即可到达终点。 + +我们定义 $\textit{last}$ 表示上一次移动的位置,变量 $\textit{mx}$ 表示当前位置能够移动到的最远位置,初始时 $\textit{last} = \textit{mx} = 0$。我们从 $i = 0$ 开始遍历,如果 $i$ 等于 $\textit{last}$,说明我们需要再次移动,此时如果 $\textit{last} = \textit{mx}$,说明我们无法再移动,返回 $-1$;否则,我们将 $\textit{last}$ 更新为 $\textit{mx}$,并将答案加一。 + +遍历结束后,返回答案即可。 + +时间复杂度 $O(n \times \log n + L)$,空间复杂度 $O(n + L)$。其中 $n$ 是字符串 $\textit{target}$ 的长度,而 $L$ 是所有有效字符串的总长度。 diff --git a/solution/3200-3299/3292.Minimum Number of Valid Strings to Form Target II/README_EN.md b/solution/3200-3299/3292.Minimum Number of Valid Strings to Form Target II/README_EN.md index cb74238cf5e90..d058385e811b1 100644 --- a/solution/3200-3299/3292.Minimum Number of Valid Strings to Form Target II/README_EN.md +++ b/solution/3200-3299/3292.Minimum Number of Valid Strings to Form Target II/README_EN.md @@ -93,7 +93,25 @@ tags: -### Solution 1 +### Solution 1: String Hashing + Binary Search + Greedy + +Due to the large data scale of this problem, using the "Trie + Memoization" method will time out. We need to find a more efficient solution. + +Consider starting from the $i$-th character of the string $\textit{target}$ and finding the maximum matching substring length, denoted as $\textit{dist}$. For any $j \in [i, i + \textit{dist} - 1]$, we can find a string in $\textit{words}$ such that $\textit{target}[i..j]$ is a prefix of this string. This has a monotonic property, so we can use binary search to determine $\textit{dist}$. + +Specifically, we first preprocess the hash values of all prefixes of strings in $\textit{words}$ and store them in the array $\textit{s}$ grouped by prefix length. Additionally, we preprocess the hash values of $\textit{target}$ and store them in $\textit{hashing}$ to facilitate querying the hash value of any $\textit{target}[l..r]$. + +Next, we design a function $\textit{f}(i)$ to represent the maximum matching substring length starting from the $i$-th character of the string $\textit{target}$. We can determine $\textit{f}(i)$ using binary search. + +Define the left boundary of the binary search as $l = 0$ and the right boundary as $r = \min(n - i, m)$, where $n$ is the length of the string $\textit{target}$ and $m$ is the maximum length of strings in $\textit{words}$. During the binary search, we need to check if $\textit{target}[i..i+\textit{mid}-1]$ is one of the hash values in $\textit{s}[\textit{mid}]$. If it is, update the left boundary $l$ to $\textit{mid}$; otherwise, update the right boundary $r$ to $\textit{mid} - 1$. After the binary search, return $l$. + +After calculating $\textit{f}(i)$, the problem becomes a classic greedy problem. Starting from $i = 0$, for each position $i$, the farthest position we can move to is $i + \textit{f}(i)$. We need to find the minimum number of moves to reach the end. + +We define $\textit{last}$ to represent the last moved position and $\textit{mx}$ to represent the farthest position we can move to from the current position. Initially, $\textit{last} = \textit{mx} = 0$. We traverse from $i = 0$. If $i$ equals $\textit{last}$, it means we need to move again. If $\textit{last} = \textit{mx}$, it means we cannot move further, so we return $-1$. Otherwise, we update $\textit{last}$ to $\textit{mx}$ and increment the answer by one. + +After the traversal, return the answer. + +The time complexity is $O(n \times \log n + L)$, and the space complexity is $O(n + L)$. Here, $n$ is the length of the string $\textit{target}$, and $L$ is the total length of all valid strings. diff --git a/solution/3300-3399/3387.Maximize Amount After Two Days of Conversions/README.md b/solution/3300-3399/3387.Maximize Amount After Two Days of Conversions/README.md index a40364db71f11..960841d6c22e0 100644 --- a/solution/3300-3399/3387.Maximize Amount After Two Days of Conversions/README.md +++ b/solution/3300-3399/3387.Maximize Amount After Two Days of Conversions/README.md @@ -103,6 +103,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3387.Ma
rates2.length == m
1.0 <= rates1[i], rates2[i] <= 10.0
5 * 1010
。rates2.length == m
1.0 <= rates1[i], rates2[i] <= 10.0
5 * 1010
.nums
分为三段 非空子数组:nums1
,nums2
和 nums3
,三个数组 nums1
,nums2
和 nums3
按顺序连接可以得到 nums
。nums1
是子数组 nums2
的前缀 或者 nums2
是 nums3
的前缀。请你返回满足以上条件的分割 数目 。
diff --git a/solution/3300-3399/3388.Count Beautiful Splits in an Array/README_EN.md b/solution/3300-3399/3388.Count Beautiful Splits in an Array/README_EN.md index 967b96112f372..92562c3606a5e 100644 --- a/solution/3300-3399/3388.Count Beautiful Splits in an Array/README_EN.md +++ b/solution/3300-3399/3388.Count Beautiful Splits in an Array/README_EN.md @@ -19,17 +19,12 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3388.CoA split of an array nums
is beautiful if:
nums
is split into three non-empty subarrays: nums1
, nums2
, and nums3
, such that nums
can be formed by concatenating nums1
, nums2
, and nums3
in that order.nums1
is a prefix of nums2
OR nums2
is a prefix of nums3
.nums
is split into three subarrays: nums1
, nums2
, and nums3
, such that nums
can be formed by concatenating nums1
, nums2
, and nums3
in that order.nums1
is a prefix of nums2
OR nums2
is a prefix of nums3
.Return the number of ways you can make this split.
-A subarray is a contiguous non-empty sequence of elements within an array.
- -A prefix of an array is a subarray that starts from the beginning of the array and extends to any point within it.
-
Example 1:
diff --git a/solution/3300-3399/3389.Minimum Operations to Make Character Frequencies Equal/README.md b/solution/3300-3399/3389.Minimum Operations to Make Character Frequencies Equal/README.md index 5f65810652043..47afde02be219 100644 --- a/solution/3300-3399/3389.Minimum Operations to Make Character Frequencies Equal/README.md +++ b/solution/3300-3399/3389.Minimum Operations to Make Character Frequencies Equal/README.md @@ -25,7 +25,6 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3389.Mis
中添加一个字符。s
中一个字母变成字母表中下一个字母。注意 ,第三个操作不能将 'z'
变为 'a'
。
s
.s
to its next letter in the alphabet.Note that you cannot change 'z'
to 'a'
using the third operation.