diff --git a/solution/2600-2699/2645.Minimum Additions to Make Valid String/README_EN.md b/solution/2600-2699/2645.Minimum Additions to Make Valid String/README_EN.md index 6d8cc00d1b0ad..396163b142074 100644 --- a/solution/2600-2699/2645.Minimum Additions to Make Valid String/README_EN.md +++ b/solution/2600-2699/2645.Minimum Additions to Make Valid String/README_EN.md @@ -43,6 +43,18 @@ ## Solutions +**Solution 1: Greedy + Two Pointers** + +We define the string $s$ as `"abc"`, and use pointers $i$ and $j$ to point to $s$ and $word$ respectively. + +If $word[j] \neq s[i]$, we need to insert $s[i]$, and we add $1$ to the answer; otherwise, it means that $word[j]$ can match with $s[i]$, and we move $j$ one step to the right. + +Then, we move $i$ one step to the right, i.e., $i = (i + 1) \bmod 3$. We continue the above operations until $j$ reaches the end of the string $word$. + +Finally, we check whether the last character of $word$ is `'b'` or `'a'`. If it is, we need to insert `'c'` or `'bc'`, and we add $1$ or $2$ to the answer and return it. + +The time complexity is $O(n)$, where $n$ is the length of the string $word$. The space complexity is $O(1)$. + ### **Python3** diff --git a/solution/2600-2699/2696.Minimum String Length After Removing Substrings/README.md b/solution/2600-2699/2696.Minimum String Length After Removing Substrings/README.md index 5257da0353609..953d13adc5d86 100644 --- a/solution/2600-2699/2696.Minimum String Length After Removing Substrings/README.md +++ b/solution/2600-2699/2696.Minimum String Length After Removing Substrings/README.md @@ -55,6 +55,8 @@ 最后栈中剩余的元素个数就是最终字符串的长度。 +> 在实现上,我们可以在栈中预先放入一个空字符,这样就不需要在遍历字符串时判断栈是否为空了,最后返回栈的大小减一即可。 + 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是字符串 $s$ 的长度。 @@ -137,9 +139,9 @@ func minLength(s string) int { function minLength(s: string): number { const stk: string[] = ['']; for (const c of s) { - if (c === 'B' && stk[stk.length - 1] === 'A') { + if (c === 'B' && stk.at(-1)! === 'A') { stk.pop(); - } else if (c === 'D' && stk[stk.length - 1] === 'C') { + } else if (c === 'D' && stk.at(-1)! === 'C') { stk.pop(); } else { stk.push(c); diff --git a/solution/2600-2699/2696.Minimum String Length After Removing Substrings/README_EN.md b/solution/2600-2699/2696.Minimum String Length After Removing Substrings/README_EN.md index d907ad41ad2f9..3da6fa695a1ce 100644 --- a/solution/2600-2699/2696.Minimum String Length After Removing Substrings/README_EN.md +++ b/solution/2600-2699/2696.Minimum String Length After Removing Substrings/README_EN.md @@ -43,6 +43,16 @@ It can be shown that it is the minimum length that we can obtain. ## Solutions +**Solution 1: Stack** + +We traverse the string $s$. For the current character $c$ we are traversing, if the stack is not empty and the top element of the stack $top$ can form $AB$ or $CD$ with $c$, then we pop the top element of the stack, otherwise we push $c$ into the stack. + +The number of remaining elements in the stack is the length of the final string. + +> In implementation, we can pre-place an empty character in the stack, so there is no need to judge whether the stack is empty when traversing the string. Finally, we can return the size of the stack minus one. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the string $s$. + ### **Python3** @@ -119,9 +129,9 @@ func minLength(s string) int { function minLength(s: string): number { const stk: string[] = ['']; for (const c of s) { - if (c === 'B' && stk[stk.length - 1] === 'A') { + if (c === 'B' && stk.at(-1)! === 'A') { stk.pop(); - } else if (c === 'D' && stk[stk.length - 1] === 'C') { + } else if (c === 'D' && stk.at(-1)! === 'C') { stk.pop(); } else { stk.push(c); diff --git a/solution/2600-2699/2696.Minimum String Length After Removing Substrings/Solution.ts b/solution/2600-2699/2696.Minimum String Length After Removing Substrings/Solution.ts index cd1e5c6817c42..0828f838631a7 100644 --- a/solution/2600-2699/2696.Minimum String Length After Removing Substrings/Solution.ts +++ b/solution/2600-2699/2696.Minimum String Length After Removing Substrings/Solution.ts @@ -1,9 +1,9 @@ function minLength(s: string): number { const stk: string[] = ['']; for (const c of s) { - if (c === 'B' && stk[stk.length - 1] === 'A') { + if (c === 'B' && stk.at(-1)! === 'A') { stk.pop(); - } else if (c === 'D' && stk[stk.length - 1] === 'C') { + } else if (c === 'D' && stk.at(-1)! === 'C') { stk.pop(); } else { stk.push(c); diff --git a/solution/2600-2699/2698.Find the Punishment Number of an Integer/README_EN.md b/solution/2600-2699/2698.Find the Punishment Number of an Integer/README_EN.md index f862e6b824a87..2f22cd1f4a122 100644 --- a/solution/2600-2699/2698.Find the Punishment Number of an Integer/README_EN.md +++ b/solution/2600-2699/2698.Find the Punishment Number of an Integer/README_EN.md @@ -48,6 +48,14 @@ Hence, the punishment number of 37 is 1 + 81 + 100 + 1296 = 1478 ## Solutions +**Solution 1: Enumeration + DFS** + +We enumerate $i$, where $1 \leq i \leq n$. For each $i$, we split the decimal representation string of $x = i^2$, and then check whether it meets the requirements of the problem. If it does, we add $x$ to the answer. + +After the enumeration ends, we return the answer. + +The time complexity is $O(n^{1 + 2 \log_{10}^2})$, and the space complexity is $O(\log n)$, where $n$ is the given positive integer. + ### **Python3** diff --git a/solution/2600-2699/2699.Modify Graph Edge Weights/README_EN.md b/solution/2600-2699/2699.Modify Graph Edge Weights/README_EN.md index 7dc2a645ef4f9..cee975e8c8f61 100644 --- a/solution/2600-2699/2699.Modify Graph Edge Weights/README_EN.md +++ b/solution/2600-2699/2699.Modify Graph Edge Weights/README_EN.md @@ -63,6 +63,21 @@ ## Solutions +**Solution 1: Shortest Path (Dijkstra's Algorithm)** + +First, we ignore the edges with a weight of $-1$ and use Dijkstra's algorithm to find the shortest distance $d$ from $source$ to $destination$. + +- If $d < target$, it means there is a shortest path composed entirely of positive weight edges. No matter how we modify the edges with a weight of $-1$, we cannot make the shortest distance from $source$ to $destination$ equal to $target$. Therefore, there is no modification scheme that satisfies the problem, and we can return an empty array. + +- If $d = target$, it means there is a shortest path composed entirely of positive weight edges, and its length is $target$. In this case, we can modify all edges with a weight of $-1$ to the maximum value $2 \times 10^9$. + +- If $d > target$, we can try to add an edge with a weight of $-1$ to the graph, set the weight of the edge to $1$, and then use Dijkstra's algorithm again to find the shortest distance $d$ from $source$ to $destination$. + + - If the shortest distance $d \leq target$, it means that after adding this edge, the shortest path can be shortened, and the shortest path must pass through this edge. Then we only need to change the weight of this edge to $target-d+1$ to make the shortest path equal to $target$. Then we can modify the remaining edges with a weight of $-1$ to the maximum value $2 \times 10^9$. + - If the shortest distance $d > target$, it means that after adding this edge, the shortest path will not be shortened. Then we greedily keep the weight of this edge as $-1$ and continue to try to add the remaining edges with a weight of $-1$. + +The time complexity is $O(n^3)$, and the space complexity is $O(n^2)$, where $n$ is the number of points in the graph. + ### **Python3** diff --git a/solution/2700-2799/2707.Extra Characters in a String/README.md b/solution/2700-2799/2707.Extra Characters in a String/README.md index b8affafbddede..fa36e8a444be9 100644 --- a/solution/2700-2799/2707.Extra Characters in a String/README.md +++ b/solution/2700-2799/2707.Extra Characters in a String/README.md @@ -42,6 +42,36 @@ +**方法一:哈希表 + 动态规划** + +我们可以用一个哈希表 $ss$ 记录字段中的所有单词,方便我们快速判断一个字符串是否在字典中。 + +接下来,我们定义 $f[i]$ 表示字符串 $s$ 的前 $i$ 个字符的最小额外字符数,初始时 $f[0] = 0$。 + +当 $i \ge 1$ 时,第 $i$ 个字符 $s[i - 1]$ 可以作为一个额外字符,此时 $f[i] = f[i - 1] + 1$,如果在 $j \in [0, i - 1]$ 中存在一个下标 $j$,使得 $s[j..i)$ 在哈希表 $ss$ 中,那么我们可以将 $s[j..i)$ 作为一个单词,此时 $f[i] = f[j]$。 + +综上,我们可以得到状态转移方程: + +$$ +f[i] = \min \{ f[i - 1] + 1, \min_{j \in [0, i - 1]} f[j] \} +$$ + +其中 $i \ge 1$,而 $j \in [0, i - 1]$ 且 $s[j..i)$ 在哈希表 $ss$ 中。 + +最终答案为 $f[n]$。 + +时间复杂度 $O(n^3 + L)$,空间复杂度 $O(n + L)$。其中 $n$ 是字符串 $s$ 的长度,而 $L$ 是字典中所有单词的长度之和。 + +**方法二:字典树 + 动态规划** + +我们可以借助字典树来优化方法一的时间复杂度。 + +具体地,我们首先将字典中的每个单词逆序插入到字典树 $root$ 中,然后我们定义 $f[i]$ 表示字符串 $s$ 的前 $i$ 个字符的最小额外字符数,初始时 $f[0] = 0$。 + +当 $i \ge 1$ 时,第 $i$ 个字符 $s[i - 1]$ 可以作为一个额外字符,此时 $f[i] = f[i - 1] + 1$;我们也可以在 $[0..i-1]$ 的范围内逆序枚举下标 $j$,判断 $s[j..i)$ 是否在字典树 $root$ 中,如果存在,那么我们可以将 $s[j..i)$ 作为一个单词,此时 $f[i] = f[j]$。 + +时间复杂度 $O(n^2 + L)$,空间复杂度 $O(n + L \times |\Sigma|)$。其中 $n$ 是字符串 $s$ 的长度,而 $L$ 是字典中所有单词的长度之和,另外 $|\Sigma|$ 是字符集的大小,本题中字符集为小写英文字母,因此 $|\Sigma| = 26$。 + ### **Python3** @@ -62,6 +92,41 @@ class Solution: return f[n] ``` +```python +class Node: + __slots__ = ['children', 'is_end'] + + def __init__(self): + self.children: List[Node | None] = [None] * 26 + self.is_end = False + + +class Solution: + def minExtraChar(self, s: str, dictionary: List[str]) -> int: + root = Node() + for w in dictionary: + node = root + for c in w[::-1]: + i = ord(c) - ord('a') + if node.children[i] is None: + node.children[i] = Node() + node = node.children[i] + node.is_end = True + + n = len(s) + f = [0] * (n + 1) + for i in range(1, n + 1): + f[i] = f[i - 1] + 1 + node = root + for j in range(i - 1, -1, -1): + node = node.children[ord(s[j]) - ord('a')] + if node is None: + break + if node.is_end and f[j] < f[i]: + f[i] = f[j] + return f[n] +``` + ### **Java** @@ -89,6 +154,46 @@ class Solution { } ``` +```java +class Node { + Node[] children = new Node[26]; + boolean isEnd; +} + +class Solution { + public int minExtraChar(String s, String[] dictionary) { + Node root = new Node(); + for (String w : dictionary) { + Node node = root; + for (int k = w.length() - 1; k >= 0; --k) { + int i = w.charAt(k) - 'a'; + if (node.children[i] == null) { + node.children[i] = new Node(); + } + node = node.children[i]; + } + node.isEnd = true; + } + int n = s.length(); + int[] f = new int[n + 1]; + for (int i = 1; i <= n; ++i) { + f[i] = f[i - 1] + 1; + Node node = root; + for (int j = i - 1; j >= 0; --j) { + node = node.children[s.charAt(j) - 'a']; + if (node == null) { + break; + } + if (node.isEnd && f[j] < f[i]) { + f[i] = f[j]; + } + } + } + return f[n]; + } +} +``` + ### **C++** ```cpp @@ -112,37 +217,51 @@ public: }; ``` -### **Rust** - -```rust -use std::collections::HashSet; - -impl Solution { - #[allow(dead_code)] - pub fn min_extra_char(s: String, dictionary: Vec) -> i32 { - let n = s.len(); - let mut set = dictionary - .iter() - .map(|s| s.into()) - .collect::>(); - let mut dp = vec![0; n + 1]; - - // Initialize the dp vector - dp[0] = 0; +```cpp +class Node { +public: + Node* children[26]; + bool isEnd = false; + Node() { + fill(children, children + 26, nullptr); + } +}; - // Begin the actual dp process - for i in 1..=n { - dp[i] = dp[i - 1] + 1; - for j in 0..i { - if set.contains(&s[j..i]) { - dp[i] = std::cmp::min(dp[i], dp[j]); +class Solution { +public: + int minExtraChar(string s, vector& dictionary) { + Node* root = new Node(); + for (const string& w : dictionary) { + Node* node = root; + for (int k = w.length() - 1; k >= 0; --k) { + int i = w[k] - 'a'; + if (node->children[i] == nullptr) { + node->children[i] = new Node(); } + node = node->children[i]; } + node->isEnd = true; } - dp[n] + int n = s.size(); + int f[n + 1]; + f[0] = 0; + for (int i = 1; i <= n; ++i) { + f[i] = f[i - 1] + 1; + Node* node = root; + for (int j = i - 1; ~j; --j) { + node = node->children[s[j] - 'a']; + if (node == nullptr) { + break; + } + if (node->isEnd && f[j] < f[i]) { + f[i] = f[j]; + } + } + } + return f[n]; } -} +}; ``` ### **Go** @@ -167,6 +286,45 @@ func minExtraChar(s string, dictionary []string) int { } ``` +```go +type Node struct { + children [26]*Node + isEnd bool +} + +func minExtraChar(s string, dictionary []string) int { + root := &Node{} + for _, w := range dictionary { + node := root + for k := len(w) - 1; k >= 0; k-- { + i := int(w[k] - 'a') + if node.children[i] == nil { + node.children[i] = &Node{} + } + node = node.children[i] + } + node.isEnd = true + } + + n := len(s) + f := make([]int, n+1) + for i := 1; i <= n; i++ { + f[i] = f[i-1] + 1 + node := root + for j := i - 1; j >= 0; j-- { + node = node.children[int(s[j]-'a')] + if node == nil { + break + } + if node.isEnd && f[j] < f[i] { + f[i] = f[j] + } + } + } + return f[n] +} +``` + ### **TypeScript** ```ts @@ -186,6 +344,69 @@ function minExtraChar(s: string, dictionary: string[]): number { } ``` +```ts +class Node { + children: (Node | null)[] = Array(26).fill(null); + isEnd: boolean = false; +} + +function minExtraChar(s: string, dictionary: string[]): number { + const root = new Node(); + for (const w of dictionary) { + let node = root; + for (let k = w.length - 1; ~k; --k) { + const i = w.charCodeAt(k) - 'a'.charCodeAt(0); + if (node.children[i] === null) { + node.children[i] = new Node(); + } + node = node.children[i] as Node; + } + node.isEnd = true; + } + + const n = s.length; + const f: number[] = Array(n + 1).fill(0); + for (let i = 1; i <= n; ++i) { + f[i] = f[i - 1] + 1; + let node = root; + for (let j = i - 1; ~j; --j) { + node = (node.children[s.charCodeAt(j) - 'a'.charCodeAt(0)] as Node) || null; + if (node === null) { + break; + } + if (node.isEnd && f[j] < f[i]) { + f[i] = f[j]; + } + } + } + + return f[n]; +} +``` + +### **Rust** + +```rust +use std::collections::HashSet; + +impl Solution { + pub fn min_extra_char(s: String, dictionary: Vec) -> i32 { + let ss: HashSet = dictionary.into_iter().collect(); + let n = s.len(); + let mut f = vec![0; n + 1]; + for i in 1..=n { + f[i] = f[i - 1] + 1; + for j in 0..i { + if ss.contains(&s[j..i]) { + f[i] = f[i].min(f[j]); + } + } + } + f[n] + } +} +``` + ### **...** ``` diff --git a/solution/2700-2799/2707.Extra Characters in a String/README_EN.md b/solution/2700-2799/2707.Extra Characters in a String/README_EN.md index a561769c5ca3b..60681ab6ef083 100644 --- a/solution/2700-2799/2707.Extra Characters in a String/README_EN.md +++ b/solution/2700-2799/2707.Extra Characters in a String/README_EN.md @@ -39,6 +39,36 @@ ## Solutions +**Solution 1: Hash Table + Dynamic Programming** + +We can use a hash table $ss$ to record all words in the dictionary, which allows us to quickly determine whether a string is in the dictionary. + +Next, we define $f[i]$ to represent the minimum number of extra characters in the first $i$ characters of string $s$, initially $f[0] = 0$. + +When $i \ge 1$, the $i$th character $s[i - 1]$ can be an extra character, in which case $f[i] = f[i - 1] + 1$. If there exists an index $j \in [0, i - 1]$ such that $s[j..i)$ is in the hash table $ss$, then we can take $s[j..i)$ as a word, in which case $f[i] = f[j]$. + +In summary, we can get the state transition equation: + +$$ +f[i] = \min \{ f[i - 1] + 1, \min_{j \in [0, i - 1]} f[j] \} +$$ + +where $i \ge 1$, and $j \in [0, i - 1]$ and $s[j..i)$ is in the hash table $ss$. + +The final answer is $f[n]$. + +The time complexity is $O(n^3 + L)$, and the space complexity is $O(n + L)$. Here, $n$ is the length of string $s$, and $L$ is the sum of the lengths of all words in the dictionary. + +**Solution 2: Trie + Dynamic Programming** + +We can use a trie to optimize the time complexity of Solution 1. + +Specifically, we first insert each word in the dictionary into the trie $root$ in reverse order, then we define $f[i]$ to represent the minimum number of extra characters in the first $i$ characters of string $s$, initially $f[0] = 0$. + +When $i \ge 1$, the $i$th character $s[i - 1]$ can be an extra character, in which case $f[i] = f[i - 1] + 1$. We can also enumerate the index $j$ in reverse order in the range $[0..i-1]$, and determine whether $s[j..i)$ is in the trie $root$. If it exists, then we can take $s[j..i)$ as a word, in which case $f[i] = f[j]$. + +The time complexity is $O(n^2 + L)$, and the space complexity is $O(n + L \times |\Sigma|)$. Here, $n$ is the length of string $s$, and $L$ is the sum of the lengths of all words in the dictionary. Additionally, $|\Sigma|$ is the size of the character set. In this problem, the character set is lowercase English letters, so $|\Sigma| = 26$. + ### **Python3** @@ -57,6 +87,41 @@ class Solution: return f[n] ``` +```python +class Node: + __slots__ = ['children', 'is_end'] + + def __init__(self): + self.children: List[Node | None] = [None] * 26 + self.is_end = False + + +class Solution: + def minExtraChar(self, s: str, dictionary: List[str]) -> int: + root = Node() + for w in dictionary: + node = root + for c in w[::-1]: + i = ord(c) - ord('a') + if node.children[i] is None: + node.children[i] = Node() + node = node.children[i] + node.is_end = True + + n = len(s) + f = [0] * (n + 1) + for i in range(1, n + 1): + f[i] = f[i - 1] + 1 + node = root + for j in range(i - 1, -1, -1): + node = node.children[ord(s[j]) - ord('a')] + if node is None: + break + if node.is_end and f[j] < f[i]: + f[i] = f[j] + return f[n] +``` + ### **Java** ```java @@ -82,6 +147,46 @@ class Solution { } ``` +```java +class Node { + Node[] children = new Node[26]; + boolean isEnd; +} + +class Solution { + public int minExtraChar(String s, String[] dictionary) { + Node root = new Node(); + for (String w : dictionary) { + Node node = root; + for (int k = w.length() - 1; k >= 0; --k) { + int i = w.charAt(k) - 'a'; + if (node.children[i] == null) { + node.children[i] = new Node(); + } + node = node.children[i]; + } + node.isEnd = true; + } + int n = s.length(); + int[] f = new int[n + 1]; + for (int i = 1; i <= n; ++i) { + f[i] = f[i - 1] + 1; + Node node = root; + for (int j = i - 1; j >= 0; --j) { + node = node.children[s.charAt(j) - 'a']; + if (node == null) { + break; + } + if (node.isEnd && f[j] < f[i]) { + f[i] = f[j]; + } + } + } + return f[n]; + } +} +``` + ### **C++** ```cpp @@ -105,37 +210,51 @@ public: }; ``` -### **Rust** - -```rust -use std::collections::HashSet; - -impl Solution { - #[allow(dead_code)] - pub fn min_extra_char(s: String, dictionary: Vec) -> i32 { - let n = s.len(); - let mut set = dictionary - .iter() - .map(|s| s.into()) - .collect::>(); - let mut dp = vec![0; n + 1]; - - // Initialize the dp vector - dp[0] = 0; +```cpp +class Node { +public: + Node* children[26]; + bool isEnd = false; + Node() { + fill(children, children + 26, nullptr); + } +}; - // Begin the actual dp process - for i in 1..=n { - dp[i] = dp[i - 1] + 1; - for j in 0..i { - if set.contains(&s[j..i]) { - dp[i] = std::cmp::min(dp[i], dp[j]); +class Solution { +public: + int minExtraChar(string s, vector& dictionary) { + Node* root = new Node(); + for (const string& w : dictionary) { + Node* node = root; + for (int k = w.length() - 1; k >= 0; --k) { + int i = w[k] - 'a'; + if (node->children[i] == nullptr) { + node->children[i] = new Node(); } + node = node->children[i]; } + node->isEnd = true; } - dp[n] + int n = s.size(); + int f[n + 1]; + f[0] = 0; + for (int i = 1; i <= n; ++i) { + f[i] = f[i - 1] + 1; + Node* node = root; + for (int j = i - 1; ~j; --j) { + node = node->children[s[j] - 'a']; + if (node == nullptr) { + break; + } + if (node->isEnd && f[j] < f[i]) { + f[i] = f[j]; + } + } + } + return f[n]; } -} +}; ``` ### **Go** @@ -160,6 +279,45 @@ func minExtraChar(s string, dictionary []string) int { } ``` +```go +type Node struct { + children [26]*Node + isEnd bool +} + +func minExtraChar(s string, dictionary []string) int { + root := &Node{} + for _, w := range dictionary { + node := root + for k := len(w) - 1; k >= 0; k-- { + i := int(w[k] - 'a') + if node.children[i] == nil { + node.children[i] = &Node{} + } + node = node.children[i] + } + node.isEnd = true + } + + n := len(s) + f := make([]int, n+1) + for i := 1; i <= n; i++ { + f[i] = f[i-1] + 1 + node := root + for j := i - 1; j >= 0; j-- { + node = node.children[int(s[j]-'a')] + if node == nil { + break + } + if node.isEnd && f[j] < f[i] { + f[i] = f[j] + } + } + } + return f[n] +} +``` + ### **TypeScript** ```ts @@ -179,6 +337,69 @@ function minExtraChar(s: string, dictionary: string[]): number { } ``` +```ts +class Node { + children: (Node | null)[] = Array(26).fill(null); + isEnd: boolean = false; +} + +function minExtraChar(s: string, dictionary: string[]): number { + const root = new Node(); + for (const w of dictionary) { + let node = root; + for (let k = w.length - 1; ~k; --k) { + const i = w.charCodeAt(k) - 'a'.charCodeAt(0); + if (node.children[i] === null) { + node.children[i] = new Node(); + } + node = node.children[i] as Node; + } + node.isEnd = true; + } + + const n = s.length; + const f: number[] = Array(n + 1).fill(0); + for (let i = 1; i <= n; ++i) { + f[i] = f[i - 1] + 1; + let node = root; + for (let j = i - 1; ~j; --j) { + node = (node.children[s.charCodeAt(j) - 'a'.charCodeAt(0)] as Node) || null; + if (node === null) { + break; + } + if (node.isEnd && f[j] < f[i]) { + f[i] = f[j]; + } + } + } + + return f[n]; +} +``` + +### **Rust** + +```rust +use std::collections::HashSet; + +impl Solution { + pub fn min_extra_char(s: String, dictionary: Vec) -> i32 { + let ss: HashSet = dictionary.into_iter().collect(); + let n = s.len(); + let mut f = vec![0; n + 1]; + for i in 1..=n { + f[i] = f[i - 1] + 1; + for j in 0..i { + if ss.contains(&s[j..i]) { + f[i] = f[i].min(f[j]); + } + } + } + f[n] + } +} +``` + ### **...** ``` diff --git a/solution/2700-2799/2707.Extra Characters in a String/Solution.rs b/solution/2700-2799/2707.Extra Characters in a String/Solution.rs index 80051c32beb3c..fd49b4d3d2ee9 100644 --- a/solution/2700-2799/2707.Extra Characters in a String/Solution.rs +++ b/solution/2700-2799/2707.Extra Characters in a String/Solution.rs @@ -1,28 +1,18 @@ use std::collections::HashSet; impl Solution { - #[allow(dead_code)] pub fn min_extra_char(s: String, dictionary: Vec) -> i32 { + let ss: HashSet = dictionary.into_iter().collect(); let n = s.len(); - let mut set = dictionary - .iter() - .map(|s| s.into()) - .collect::>(); - let mut dp = vec![0; n + 1]; - - // Initialize the dp vector - dp[0] = 0; - - // Begin the actual dp process + let mut f = vec![0; n + 1]; for i in 1..=n { - dp[i] = dp[i - 1] + 1; + f[i] = f[i - 1] + 1; for j in 0..i { - if set.contains(&s[j..i]) { - dp[i] = std::cmp::min(dp[i], dp[j]); + if ss.contains(&s[j..i]) { + f[i] = f[i].min(f[j]); } } } - - dp[n] + f[n] } }