From 5f7d29efb62f90e436cc05334eb1b8596659b14d Mon Sep 17 00:00:00 2001 From: yanglbme Date: Tue, 4 Jun 2024 08:52:47 +0800 Subject: [PATCH] feat: update solutions to lc problems: No.433,2486 --- .../0300-0399/0393.UTF-8 Validation/README.md | 12 +- .../0393.UTF-8 Validation/README_EN.md | 12 +- .../0433.Minimum Genetic Mutation/README.md | 348 +++++------------ .../README_EN.md | 350 +++++------------- .../Solution.cpp | 36 +- .../0433.Minimum Genetic Mutation/Solution.go | 38 +- .../Solution.java | 46 ++- .../0433.Minimum Genetic Mutation/Solution.py | 24 +- .../0433.Minimum Genetic Mutation/Solution.rs | 44 +-- .../Solution2.cpp | 31 -- .../Solution2.go | 35 -- .../Solution2.java | 35 -- .../Solution2.py | 19 - .../1300-1399/1306.Jump Game III/README_EN.md | 12 +- .../README.md | 65 ++-- .../README_EN.md | 65 ++-- .../Solution.cpp | 13 +- .../Solution.go | 13 +- .../Solution.java | 13 +- .../Solution.py | 13 +- .../Solution.ts | 9 +- 21 files changed, 376 insertions(+), 857 deletions(-) delete mode 100644 solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.cpp delete mode 100644 solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.go delete mode 100644 solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.java delete mode 100644 solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.py diff --git a/solution/0300-0399/0393.UTF-8 Validation/README.md b/solution/0300-0399/0393.UTF-8 Validation/README.md index c505a6e2d7044..17cbb618daf56 100644 --- a/solution/0300-0399/0393.UTF-8 Validation/README.md +++ b/solution/0300-0399/0393.UTF-8 Validation/README.md @@ -215,23 +215,23 @@ function validUtf8(data: number[]): boolean { let cnt = 0; for (const v of data) { if (cnt > 0) { - if (v >> 6 != 0b10) { + if (v >> 6 !== 0b10) { return false; } --cnt; - } else if (v >> 7 == 0) { + } else if (v >> 7 === 0) { cnt = 0; - } else if (v >> 5 == 0b110) { + } else if (v >> 5 === 0b110) { cnt = 1; - } else if (v >> 4 == 0b1110) { + } else if (v >> 4 === 0b1110) { cnt = 2; - } else if (v >> 3 == 0b11110) { + } else if (v >> 3 === 0b11110) { cnt = 3; } else { return false; } } - return cnt == 0; + return cnt === 0; } ``` diff --git a/solution/0300-0399/0393.UTF-8 Validation/README_EN.md b/solution/0300-0399/0393.UTF-8 Validation/README_EN.md index b2710dec15dcd..10ccb43c9c04f 100644 --- a/solution/0300-0399/0393.UTF-8 Validation/README_EN.md +++ b/solution/0300-0399/0393.UTF-8 Validation/README_EN.md @@ -213,23 +213,23 @@ function validUtf8(data: number[]): boolean { let cnt = 0; for (const v of data) { if (cnt > 0) { - if (v >> 6 != 0b10) { + if (v >> 6 !== 0b10) { return false; } --cnt; - } else if (v >> 7 == 0) { + } else if (v >> 7 === 0) { cnt = 0; - } else if (v >> 5 == 0b110) { + } else if (v >> 5 === 0b110) { cnt = 1; - } else if (v >> 4 == 0b1110) { + } else if (v >> 4 === 0b1110) { cnt = 2; - } else if (v >> 3 == 0b11110) { + } else if (v >> 3 === 0b11110) { cnt = 3; } else { return false; } } - return cnt == 0; + return cnt === 0; } ``` diff --git a/solution/0400-0499/0433.Minimum Genetic Mutation/README.md b/solution/0400-0499/0433.Minimum Genetic Mutation/README.md index 7e749c1fe32a4..0fba603179eb9 100644 --- a/solution/0400-0499/0433.Minimum Genetic Mutation/README.md +++ b/solution/0400-0499/0433.Minimum Genetic Mutation/README.md @@ -75,26 +75,32 @@ tags: ### 方法一:BFS +我们定义一个队列 `q`,用于存储当前基因序列以及变化的次数,定义一个集合 `vis`,用于存储已经访问过的基因序列。初始时,将起始基因序列 `start` 加入队列 `q`,并将其加入集合 `vis`。 + +然后,我们不断从队列 `q` 中取出一个基因序列,如果该基因序列等于目标基因序列,则返回当前的变化次数。否则,我们遍历基因库 `bank`,计算当前基因序列与基因库中的基因序列的差异值,如果差异值为 $1$,且基因库中的基因序列没有被访问过,则将其加入队列 `q`,并将其加入集合 `vis`。 + +如果队列 `q` 为空,说明无法完成基因变化,返回 $-1$。 + +时间复杂度 $O(C \times n \times m)$,空间复杂度 $O(n \times m)$。其中 $n$ 和 $m$ 分别表示基因序列的长度和基因库的长度,而 $C$ 表示基因序列的字符集大小,本题中 $C = 4$。 + #### Python3 ```python class Solution: - def minMutation(self, start: str, end: str, bank: List[str]) -> int: - s = set(bank) - q = deque([(start, 0)]) - mp = {'A': 'TCG', 'T': 'ACG', 'C': 'ATG', 'G': 'ATC'} + def minMutation(self, startGene: str, endGene: str, bank: List[str]) -> int: + q = deque([(startGene, 0)]) + vis = {startGene} while q: - t, step = q.popleft() - if t == end: - return step - for i, v in enumerate(t): - for j in mp[v]: - next = t[:i] + j + t[i + 1 :] - if next in s: - q.append((next, step + 1)) - s.remove(next) + gene, depth = q.popleft() + if gene == endGene: + return depth + for nxt in bank: + diff = sum(a != b for a, b in zip(gene, nxt)) + if diff == 1 and nxt not in vis: + q.append((nxt, depth + 1)) + vis.add(nxt) return -1 ``` @@ -102,34 +108,32 @@ class Solution: ```java class Solution { - public int minMutation(String start, String end, String[] bank) { - Set s = new HashSet<>(); - for (String b : bank) { - s.add(b); - } - Map mp = new HashMap<>(4); - mp.put('A', "TCG"); - mp.put('T', "ACG"); - mp.put('C', "ATG"); - mp.put('G', "ATC"); - Deque> q = new LinkedList<>(); - q.offer(new Pair<>(start, 0)); + public int minMutation(String startGene, String endGene, String[] bank) { + Deque q = new ArrayDeque<>(); + q.offer(startGene); + Set vis = new HashSet<>(); + vis.add(startGene); + int depth = 0; while (!q.isEmpty()) { - Pair p = q.poll(); - String t = p.getKey(); - int step = p.getValue(); - if (end.equals(t)) { - return step; - } - for (int i = 0; i < t.length(); ++i) { - for (char c : mp.get(t.charAt(i)).toCharArray()) { - String next = t.substring(0, i) + c + t.substring(i + 1); - if (s.contains(next)) { - q.offer(new Pair<>(next, step + 1)); - s.remove(next); + for (int m = q.size(); m > 0; --m) { + String gene = q.poll(); + if (gene.equals(endGene)) { + return depth; + } + for (String next : bank) { + int c = 2; + for (int k = 0; k < 8 && c > 0; ++k) { + if (gene.charAt(k) != next.charAt(k)) { + --c; + } + } + if (c > 0 && !vis.contains(next)) { + q.offer(next); + vis.add(next); } } } + ++depth; } return -1; } @@ -141,29 +145,23 @@ class Solution { ```cpp class Solution { public: - int minMutation(string start, string end, vector& bank) { - unordered_set s; - for (auto& b : bank) s.insert(b); - unordered_map mp; - mp['A'] = "TCG"; - mp['T'] = "ACG"; - mp['C'] = "ATG"; - mp['G'] = "ATC"; - queue> q; - q.push({start, 0}); + int minMutation(string startGene, string endGene, vector& bank) { + queue> q{{{startGene, 0}}}; + unordered_set vis = {startGene}; while (!q.empty()) { - auto p = q.front(); + auto [gene, depth] = q.front(); q.pop(); - string t = p.first; - int step = p.second; - if (t == end) return step; - for (int i = 0; i < t.size(); ++i) { - for (char c : mp[t[i]]) { - string next = t.substr(0, i) + c + t.substr(i + 1, t.size() - i - 1); - if (s.count(next)) { - q.push({next, step + 1}); - s.erase(next); - } + if (gene == endGene) { + return depth; + } + for (const string& next : bank) { + int c = 2; + for (int k = 0; k < 8 && c; ++k) { + c -= gene[k] != next[k]; + } + if (c && !vis.contains(next)) { + vis.insert(next); + q.push({next, depth + 1}); } } } @@ -175,36 +173,30 @@ public: #### Go ```go -func minMutation(start string, end string, bank []string) int { - s := make(map[string]bool) - for _, b := range bank { - s[b] = true - } - mp := make(map[byte]string) - mp['A'] = "TCG" - mp['T'] = "ACG" - mp['C'] = "ATG" - mp['G'] = "ATC" +func minMutation(startGene string, endGene string, bank []string) int { type pair struct { - first string - second int + s string + depth int } - q := []pair{{start, 0}} + q := []pair{pair{startGene, 0}} + vis := map[string]bool{startGene: true} for len(q) > 0 { p := q[0] q = q[1:] - t, step := p.first, p.second - if t == end { - return step + if p.s == endGene { + return p.depth } - for i := 0; i < len(t); i++ { - for _, c := range mp[t[i]] { - next := t[:i] + string(c) + t[i+1:] - if s[next] { - q = append(q, pair{next, step + 1}) - s[next] = false + for _, next := range bank { + diff := 0 + for i := 0; i < len(startGene); i++ { + if p.s[i] != next[i] { + diff++ } } + if diff == 1 && !vis[next] { + vis[next] = true + q = append(q, pair{next, p.depth + 1}) + } } } return -1 @@ -241,187 +233,37 @@ function minMutation(startGene: string, endGene: string, bank: string[]): number #### Rust ```rust -use std::collections::VecDeque; -impl Solution { - pub fn min_mutation(start: String, end: String, mut bank: Vec) -> i32 { - let mut queue = vec![start].into_iter().collect::>(); - let mut res = 0; - while !queue.is_empty() { - let n = queue.len(); - for _ in 0..n { - let s1 = queue.pop_front().unwrap(); - if s1 == end { - return res; - } +use std::collections::{ HashSet, VecDeque }; - for i in (0..bank.len()).rev() { - let s1 = s1.as_bytes(); - let s2 = bank[i].as_bytes(); - let mut count = 0; - for j in 0..8 { - if s1[j] != s2[j] { - count += 1; - } +impl Solution { + pub fn min_mutation(start_gene: String, end_gene: String, bank: Vec) -> i32 { + let mut q = VecDeque::new(); + q.push_back((start_gene.clone(), 0)); + let mut vis = HashSet::new(); + vis.insert(start_gene); + + while let Some((gene, depth)) = q.pop_front() { + if gene == end_gene { + return depth; + } + for next in &bank { + let mut c = 2; + for k in 0..8 { + if gene.as_bytes()[k] != next.as_bytes()[k] { + c -= 1; } - if count <= 1 { - queue.push_back(bank.remove(i)); + if c == 0 { + break; } } - } - res += 1; - } - -1 - } -} -``` - - - - - - - -### 方法二:DFS - - - -#### Python3 - -```python -class Solution: - def minMutation(self, start: str, end: str, bank: List[str]) -> int: - def dfs(start, t): - if start == end: - nonlocal ans - ans = min(ans, t) - return - for i, x in enumerate(start): - for y in 'ACGT': - if x != y: - nxt = start[:i] + y + start[i + 1 :] - if nxt in s: - s.remove(nxt) - dfs(nxt, t + 1) - - s = set(bank) - ans = inf - dfs(start, 0) - return -1 if ans == inf else ans -``` - -#### Java - -```java -class Solution { - private int ans; - private Set s; - private static final char[] seq = {'A', 'C', 'G', 'T'}; - - public int minMutation(String start, String end, String[] bank) { - s = new HashSet<>(); - for (String b : bank) { - s.add(b); - } - ans = Integer.MAX_VALUE; - dfs(start, end, 0); - s.remove(start); - return ans == Integer.MAX_VALUE ? -1 : ans; - } - - private void dfs(String start, String end, int t) { - if (start.equals(end)) { - ans = Math.min(ans, t); - return; - } - for (int i = 0; i < start.length(); ++i) { - for (char c : seq) { - if (start.charAt(i) == c) { - continue; - } - String nxt = start.substring(0, i) + c + start.substring(i + 1); - if (s.contains(nxt)) { - s.remove(nxt); - dfs(nxt, end, t + 1); - } - } - } - } -} -``` - -#### C++ - -```cpp -class Solution { -public: - int ans; - string seq = "ACGT"; - - int minMutation(string start, string end, vector& bank) { - unordered_set s; - for (auto& b : bank) s.insert(b); - ans = INT_MAX; - s.erase(start); - dfs(start, end, s, 0); - return ans == INT_MAX ? -1 : ans; - } - - void dfs(string& start, string& end, unordered_set& s, int t) { - if (start == end) { - ans = min(ans, t); - return; - } - for (int i = 0; i < start.size(); ++i) { - for (char& c : seq) { - if (start[i] == c) continue; - string nxt = start.substr(0, i) + c + start.substr(i + 1, start.size() - i - 1); - if (s.count(nxt)) { - s.erase(nxt); - dfs(nxt, end, s, t + 1); + if c > 0 && !vis.contains(next) { + vis.insert(next.clone()); + q.push_back((next.clone(), depth + 1)); } } } + -1 } -}; -``` - -#### Go - -```go -func minMutation(start string, end string, bank []string) int { - s := make(map[string]bool) - for _, b := range bank { - s[b] = true - } - ans := math.MaxInt32 - s[start] = false - seq := []rune{'A', 'C', 'G', 'T'} - var dfs func(start string, t int) - dfs = func(start string, t int) { - if start == end { - if ans > t { - ans = t - } - return - } - for i, x := range start { - for _, y := range seq { - if x == y { - continue - } - nxt := start[:i] + string(y) + start[i+1:] - if s[nxt] { - s[nxt] = false - dfs(nxt, t+1) - } - } - } - } - dfs(start, 0) - if ans == math.MaxInt32 { - return -1 - } - return ans } ``` diff --git a/solution/0400-0499/0433.Minimum Genetic Mutation/README_EN.md b/solution/0400-0499/0433.Minimum Genetic Mutation/README_EN.md index b95320f7c57d5..85a81a2e38f5b 100644 --- a/solution/0400-0499/0433.Minimum Genetic Mutation/README_EN.md +++ b/solution/0400-0499/0433.Minimum Genetic Mutation/README_EN.md @@ -62,7 +62,15 @@ tags: -### Solution 1 +### Solution 1: BFS + +We define a queue `q` to store the current gene sequence and the number of changes, and a set `vis` to store the visited gene sequences. Initially, we add the starting gene sequence `start` to the queue `q` and the set `vis`. + +Then, we continuously take out a gene sequence from the queue `q`. If this gene sequence equals the target gene sequence, we return the current number of changes. Otherwise, we iterate through the gene bank `bank`, calculate the difference value between the current gene sequence and the gene sequence in the gene bank. If the difference value is $1$ and the gene sequence in the gene bank has not been visited, we add it to the queue `q` and the set `vis`. + +If the queue `q` is empty, it means that the gene change cannot be completed, so we return $-1$. + +The time complexity is $O(C \times n \times m)$, and the space complexity is $O(n \times m)$. Where $n$ and $m$ are the lengths of the gene sequence and the gene bank respectively, and $C$ is the size of the character set of the gene sequence. In this problem, $C = 4$. @@ -70,20 +78,18 @@ tags: ```python class Solution: - def minMutation(self, start: str, end: str, bank: List[str]) -> int: - s = set(bank) - q = deque([(start, 0)]) - mp = {'A': 'TCG', 'T': 'ACG', 'C': 'ATG', 'G': 'ATC'} + def minMutation(self, startGene: str, endGene: str, bank: List[str]) -> int: + q = deque([(startGene, 0)]) + vis = {startGene} while q: - t, step = q.popleft() - if t == end: - return step - for i, v in enumerate(t): - for j in mp[v]: - next = t[:i] + j + t[i + 1 :] - if next in s: - q.append((next, step + 1)) - s.remove(next) + gene, depth = q.popleft() + if gene == endGene: + return depth + for nxt in bank: + diff = sum(a != b for a, b in zip(gene, nxt)) + if diff == 1 and nxt not in vis: + q.append((nxt, depth + 1)) + vis.add(nxt) return -1 ``` @@ -91,34 +97,32 @@ class Solution: ```java class Solution { - public int minMutation(String start, String end, String[] bank) { - Set s = new HashSet<>(); - for (String b : bank) { - s.add(b); - } - Map mp = new HashMap<>(4); - mp.put('A', "TCG"); - mp.put('T', "ACG"); - mp.put('C', "ATG"); - mp.put('G', "ATC"); - Deque> q = new LinkedList<>(); - q.offer(new Pair<>(start, 0)); + public int minMutation(String startGene, String endGene, String[] bank) { + Deque q = new ArrayDeque<>(); + q.offer(startGene); + Set vis = new HashSet<>(); + vis.add(startGene); + int depth = 0; while (!q.isEmpty()) { - Pair p = q.poll(); - String t = p.getKey(); - int step = p.getValue(); - if (end.equals(t)) { - return step; - } - for (int i = 0; i < t.length(); ++i) { - for (char c : mp.get(t.charAt(i)).toCharArray()) { - String next = t.substring(0, i) + c + t.substring(i + 1); - if (s.contains(next)) { - q.offer(new Pair<>(next, step + 1)); - s.remove(next); + for (int m = q.size(); m > 0; --m) { + String gene = q.poll(); + if (gene.equals(endGene)) { + return depth; + } + for (String next : bank) { + int c = 2; + for (int k = 0; k < 8 && c > 0; ++k) { + if (gene.charAt(k) != next.charAt(k)) { + --c; + } + } + if (c > 0 && !vis.contains(next)) { + q.offer(next); + vis.add(next); } } } + ++depth; } return -1; } @@ -130,29 +134,23 @@ class Solution { ```cpp class Solution { public: - int minMutation(string start, string end, vector& bank) { - unordered_set s; - for (auto& b : bank) s.insert(b); - unordered_map mp; - mp['A'] = "TCG"; - mp['T'] = "ACG"; - mp['C'] = "ATG"; - mp['G'] = "ATC"; - queue> q; - q.push({start, 0}); + int minMutation(string startGene, string endGene, vector& bank) { + queue> q{{{startGene, 0}}}; + unordered_set vis = {startGene}; while (!q.empty()) { - auto p = q.front(); + auto [gene, depth] = q.front(); q.pop(); - string t = p.first; - int step = p.second; - if (t == end) return step; - for (int i = 0; i < t.size(); ++i) { - for (char c : mp[t[i]]) { - string next = t.substr(0, i) + c + t.substr(i + 1, t.size() - i - 1); - if (s.count(next)) { - q.push({next, step + 1}); - s.erase(next); - } + if (gene == endGene) { + return depth; + } + for (const string& next : bank) { + int c = 2; + for (int k = 0; k < 8 && c; ++k) { + c -= gene[k] != next[k]; + } + if (c && !vis.contains(next)) { + vis.insert(next); + q.push({next, depth + 1}); } } } @@ -164,36 +162,30 @@ public: #### Go ```go -func minMutation(start string, end string, bank []string) int { - s := make(map[string]bool) - for _, b := range bank { - s[b] = true - } - mp := make(map[byte]string) - mp['A'] = "TCG" - mp['T'] = "ACG" - mp['C'] = "ATG" - mp['G'] = "ATC" +func minMutation(startGene string, endGene string, bank []string) int { type pair struct { - first string - second int + s string + depth int } - q := []pair{{start, 0}} + q := []pair{pair{startGene, 0}} + vis := map[string]bool{startGene: true} for len(q) > 0 { p := q[0] q = q[1:] - t, step := p.first, p.second - if t == end { - return step + if p.s == endGene { + return p.depth } - for i := 0; i < len(t); i++ { - for _, c := range mp[t[i]] { - next := t[:i] + string(c) + t[i+1:] - if s[next] { - q = append(q, pair{next, step + 1}) - s[next] = false + for _, next := range bank { + diff := 0 + for i := 0; i < len(startGene); i++ { + if p.s[i] != next[i] { + diff++ } } + if diff == 1 && !vis[next] { + vis[next] = true + q = append(q, pair{next, p.depth + 1}) + } } } return -1 @@ -230,187 +222,37 @@ function minMutation(startGene: string, endGene: string, bank: string[]): number #### Rust ```rust -use std::collections::VecDeque; -impl Solution { - pub fn min_mutation(start: String, end: String, mut bank: Vec) -> i32 { - let mut queue = vec![start].into_iter().collect::>(); - let mut res = 0; - while !queue.is_empty() { - let n = queue.len(); - for _ in 0..n { - let s1 = queue.pop_front().unwrap(); - if s1 == end { - return res; - } +use std::collections::{ HashSet, VecDeque }; - for i in (0..bank.len()).rev() { - let s1 = s1.as_bytes(); - let s2 = bank[i].as_bytes(); - let mut count = 0; - for j in 0..8 { - if s1[j] != s2[j] { - count += 1; - } +impl Solution { + pub fn min_mutation(start_gene: String, end_gene: String, bank: Vec) -> i32 { + let mut q = VecDeque::new(); + q.push_back((start_gene.clone(), 0)); + let mut vis = HashSet::new(); + vis.insert(start_gene); + + while let Some((gene, depth)) = q.pop_front() { + if gene == end_gene { + return depth; + } + for next in &bank { + let mut c = 2; + for k in 0..8 { + if gene.as_bytes()[k] != next.as_bytes()[k] { + c -= 1; } - if count <= 1 { - queue.push_back(bank.remove(i)); + if c == 0 { + break; } } - } - res += 1; - } - -1 - } -} -``` - - - - - - - -### Solution 2 - - - -#### Python3 - -```python -class Solution: - def minMutation(self, start: str, end: str, bank: List[str]) -> int: - def dfs(start, t): - if start == end: - nonlocal ans - ans = min(ans, t) - return - for i, x in enumerate(start): - for y in 'ACGT': - if x != y: - nxt = start[:i] + y + start[i + 1 :] - if nxt in s: - s.remove(nxt) - dfs(nxt, t + 1) - - s = set(bank) - ans = inf - dfs(start, 0) - return -1 if ans == inf else ans -``` - -#### Java - -```java -class Solution { - private int ans; - private Set s; - private static final char[] seq = {'A', 'C', 'G', 'T'}; - - public int minMutation(String start, String end, String[] bank) { - s = new HashSet<>(); - for (String b : bank) { - s.add(b); - } - ans = Integer.MAX_VALUE; - dfs(start, end, 0); - s.remove(start); - return ans == Integer.MAX_VALUE ? -1 : ans; - } - - private void dfs(String start, String end, int t) { - if (start.equals(end)) { - ans = Math.min(ans, t); - return; - } - for (int i = 0; i < start.length(); ++i) { - for (char c : seq) { - if (start.charAt(i) == c) { - continue; - } - String nxt = start.substring(0, i) + c + start.substring(i + 1); - if (s.contains(nxt)) { - s.remove(nxt); - dfs(nxt, end, t + 1); - } - } - } - } -} -``` - -#### C++ - -```cpp -class Solution { -public: - int ans; - string seq = "ACGT"; - - int minMutation(string start, string end, vector& bank) { - unordered_set s; - for (auto& b : bank) s.insert(b); - ans = INT_MAX; - s.erase(start); - dfs(start, end, s, 0); - return ans == INT_MAX ? -1 : ans; - } - - void dfs(string& start, string& end, unordered_set& s, int t) { - if (start == end) { - ans = min(ans, t); - return; - } - for (int i = 0; i < start.size(); ++i) { - for (char& c : seq) { - if (start[i] == c) continue; - string nxt = start.substr(0, i) + c + start.substr(i + 1, start.size() - i - 1); - if (s.count(nxt)) { - s.erase(nxt); - dfs(nxt, end, s, t + 1); + if c > 0 && !vis.contains(next) { + vis.insert(next.clone()); + q.push_back((next.clone(), depth + 1)); } } } + -1 } -}; -``` - -#### Go - -```go -func minMutation(start string, end string, bank []string) int { - s := make(map[string]bool) - for _, b := range bank { - s[b] = true - } - ans := math.MaxInt32 - s[start] = false - seq := []rune{'A', 'C', 'G', 'T'} - var dfs func(start string, t int) - dfs = func(start string, t int) { - if start == end { - if ans > t { - ans = t - } - return - } - for i, x := range start { - for _, y := range seq { - if x == y { - continue - } - nxt := start[:i] + string(y) + start[i+1:] - if s[nxt] { - s[nxt] = false - dfs(nxt, t+1) - } - } - } - } - dfs(start, 0) - if ans == math.MaxInt32 { - return -1 - } - return ans } ``` diff --git a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.cpp b/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.cpp index 49dcbee47352e..ef0f5bd10b0b2 100644 --- a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.cpp +++ b/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.cpp @@ -1,28 +1,22 @@ class Solution { public: - int minMutation(string start, string end, vector& bank) { - unordered_set s; - for (auto& b : bank) s.insert(b); - unordered_map mp; - mp['A'] = "TCG"; - mp['T'] = "ACG"; - mp['C'] = "ATG"; - mp['G'] = "ATC"; - queue> q; - q.push({start, 0}); + int minMutation(string startGene, string endGene, vector& bank) { + queue> q{{{startGene, 0}}}; + unordered_set vis = {startGene}; while (!q.empty()) { - auto p = q.front(); + auto [gene, depth] = q.front(); q.pop(); - string t = p.first; - int step = p.second; - if (t == end) return step; - for (int i = 0; i < t.size(); ++i) { - for (char c : mp[t[i]]) { - string next = t.substr(0, i) + c + t.substr(i + 1, t.size() - i - 1); - if (s.count(next)) { - q.push({next, step + 1}); - s.erase(next); - } + if (gene == endGene) { + return depth; + } + for (const string& next : bank) { + int c = 2; + for (int k = 0; k < 8 && c; ++k) { + c -= gene[k] != next[k]; + } + if (c && !vis.contains(next)) { + vis.insert(next); + q.push({next, depth + 1}); } } } diff --git a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.go b/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.go index 6ad8751f4c9b1..3cec2562fb693 100644 --- a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.go +++ b/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.go @@ -1,33 +1,27 @@ -func minMutation(start string, end string, bank []string) int { - s := make(map[string]bool) - for _, b := range bank { - s[b] = true - } - mp := make(map[byte]string) - mp['A'] = "TCG" - mp['T'] = "ACG" - mp['C'] = "ATG" - mp['G'] = "ATC" +func minMutation(startGene string, endGene string, bank []string) int { type pair struct { - first string - second int + s string + depth int } - q := []pair{{start, 0}} + q := []pair{pair{startGene, 0}} + vis := map[string]bool{startGene: true} for len(q) > 0 { p := q[0] q = q[1:] - t, step := p.first, p.second - if t == end { - return step + if p.s == endGene { + return p.depth } - for i := 0; i < len(t); i++ { - for _, c := range mp[t[i]] { - next := t[:i] + string(c) + t[i+1:] - if s[next] { - q = append(q, pair{next, step + 1}) - s[next] = false + for _, next := range bank { + diff := 0 + for i := 0; i < len(startGene); i++ { + if p.s[i] != next[i] { + diff++ } } + if diff == 1 && !vis[next] { + vis[next] = true + q = append(q, pair{next, p.depth + 1}) + } } } return -1 diff --git a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.java b/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.java index d55164e47591d..0a554c7e66af4 100644 --- a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.java +++ b/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.java @@ -1,32 +1,30 @@ class Solution { - public int minMutation(String start, String end, String[] bank) { - Set s = new HashSet<>(); - for (String b : bank) { - s.add(b); - } - Map mp = new HashMap<>(4); - mp.put('A', "TCG"); - mp.put('T', "ACG"); - mp.put('C', "ATG"); - mp.put('G', "ATC"); - Deque> q = new LinkedList<>(); - q.offer(new Pair<>(start, 0)); + public int minMutation(String startGene, String endGene, String[] bank) { + Deque q = new ArrayDeque<>(); + q.offer(startGene); + Set vis = new HashSet<>(); + vis.add(startGene); + int depth = 0; while (!q.isEmpty()) { - Pair p = q.poll(); - String t = p.getKey(); - int step = p.getValue(); - if (end.equals(t)) { - return step; - } - for (int i = 0; i < t.length(); ++i) { - for (char c : mp.get(t.charAt(i)).toCharArray()) { - String next = t.substring(0, i) + c + t.substring(i + 1); - if (s.contains(next)) { - q.offer(new Pair<>(next, step + 1)); - s.remove(next); + for (int m = q.size(); m > 0; --m) { + String gene = q.poll(); + if (gene.equals(endGene)) { + return depth; + } + for (String next : bank) { + int c = 2; + for (int k = 0; k < 8 && c > 0; ++k) { + if (gene.charAt(k) != next.charAt(k)) { + --c; + } + } + if (c > 0 && !vis.contains(next)) { + q.offer(next); + vis.add(next); } } } + ++depth; } return -1; } diff --git a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.py b/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.py index 80bfc78a4b807..8a17de3564b91 100644 --- a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.py +++ b/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.py @@ -1,16 +1,14 @@ class Solution: - def minMutation(self, start: str, end: str, bank: List[str]) -> int: - s = set(bank) - q = deque([(start, 0)]) - mp = {'A': 'TCG', 'T': 'ACG', 'C': 'ATG', 'G': 'ATC'} + def minMutation(self, startGene: str, endGene: str, bank: List[str]) -> int: + q = deque([(startGene, 0)]) + vis = {startGene} while q: - t, step = q.popleft() - if t == end: - return step - for i, v in enumerate(t): - for j in mp[v]: - next = t[:i] + j + t[i + 1 :] - if next in s: - q.append((next, step + 1)) - s.remove(next) + gene, depth = q.popleft() + if gene == endGene: + return depth + for nxt in bank: + diff = sum(a != b for a, b in zip(gene, nxt)) + if diff == 1 and nxt not in vis: + q.append((nxt, depth + 1)) + vis.add(nxt) return -1 diff --git a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.rs b/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.rs index 5b84f01a1f9a4..0bdd60825252f 100644 --- a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.rs +++ b/solution/0400-0499/0433.Minimum Genetic Mutation/Solution.rs @@ -1,31 +1,31 @@ -use std::collections::VecDeque; +use std::collections::{ HashSet, VecDeque }; + impl Solution { - pub fn min_mutation(start: String, end: String, mut bank: Vec) -> i32 { - let mut queue = vec![start].into_iter().collect::>(); - let mut res = 0; - while !queue.is_empty() { - let n = queue.len(); - for _ in 0..n { - let s1 = queue.pop_front().unwrap(); - if s1 == end { - return res; - } + pub fn min_mutation(start_gene: String, end_gene: String, bank: Vec) -> i32 { + let mut q = VecDeque::new(); + q.push_back((start_gene.clone(), 0)); + let mut vis = HashSet::new(); + vis.insert(start_gene); - for i in (0..bank.len()).rev() { - let s1 = s1.as_bytes(); - let s2 = bank[i].as_bytes(); - let mut count = 0; - for j in 0..8 { - if s1[j] != s2[j] { - count += 1; - } + while let Some((gene, depth)) = q.pop_front() { + if gene == end_gene { + return depth; + } + for next in &bank { + let mut c = 2; + for k in 0..8 { + if gene.as_bytes()[k] != next.as_bytes()[k] { + c -= 1; } - if count <= 1 { - queue.push_back(bank.remove(i)); + if c == 0 { + break; } } + if c > 0 && !vis.contains(next) { + vis.insert(next.clone()); + q.push_back((next.clone(), depth + 1)); + } } - res += 1; } -1 } diff --git a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.cpp b/solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.cpp deleted file mode 100644 index 3e5eece847361..0000000000000 --- a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.cpp +++ /dev/null @@ -1,31 +0,0 @@ -class Solution { -public: - int ans; - string seq = "ACGT"; - - int minMutation(string start, string end, vector& bank) { - unordered_set s; - for (auto& b : bank) s.insert(b); - ans = INT_MAX; - s.erase(start); - dfs(start, end, s, 0); - return ans == INT_MAX ? -1 : ans; - } - - void dfs(string& start, string& end, unordered_set& s, int t) { - if (start == end) { - ans = min(ans, t); - return; - } - for (int i = 0; i < start.size(); ++i) { - for (char& c : seq) { - if (start[i] == c) continue; - string nxt = start.substr(0, i) + c + start.substr(i + 1, start.size() - i - 1); - if (s.count(nxt)) { - s.erase(nxt); - dfs(nxt, end, s, t + 1); - } - } - } - } -}; \ No newline at end of file diff --git a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.go b/solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.go deleted file mode 100644 index a5f5ae5d60ad4..0000000000000 --- a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.go +++ /dev/null @@ -1,35 +0,0 @@ -func minMutation(start string, end string, bank []string) int { - s := make(map[string]bool) - for _, b := range bank { - s[b] = true - } - ans := math.MaxInt32 - s[start] = false - seq := []rune{'A', 'C', 'G', 'T'} - var dfs func(start string, t int) - dfs = func(start string, t int) { - if start == end { - if ans > t { - ans = t - } - return - } - for i, x := range start { - for _, y := range seq { - if x == y { - continue - } - nxt := start[:i] + string(y) + start[i+1:] - if s[nxt] { - s[nxt] = false - dfs(nxt, t+1) - } - } - } - } - dfs(start, 0) - if ans == math.MaxInt32 { - return -1 - } - return ans -} \ No newline at end of file diff --git a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.java b/solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.java deleted file mode 100644 index e7196592d8561..0000000000000 --- a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.java +++ /dev/null @@ -1,35 +0,0 @@ -class Solution { - private int ans; - private Set s; - private static final char[] seq = {'A', 'C', 'G', 'T'}; - - public int minMutation(String start, String end, String[] bank) { - s = new HashSet<>(); - for (String b : bank) { - s.add(b); - } - ans = Integer.MAX_VALUE; - dfs(start, end, 0); - s.remove(start); - return ans == Integer.MAX_VALUE ? -1 : ans; - } - - private void dfs(String start, String end, int t) { - if (start.equals(end)) { - ans = Math.min(ans, t); - return; - } - for (int i = 0; i < start.length(); ++i) { - for (char c : seq) { - if (start.charAt(i) == c) { - continue; - } - String nxt = start.substring(0, i) + c + start.substring(i + 1); - if (s.contains(nxt)) { - s.remove(nxt); - dfs(nxt, end, t + 1); - } - } - } - } -} \ No newline at end of file diff --git a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.py b/solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.py deleted file mode 100644 index 6c971f3def542..0000000000000 --- a/solution/0400-0499/0433.Minimum Genetic Mutation/Solution2.py +++ /dev/null @@ -1,19 +0,0 @@ -class Solution: - def minMutation(self, start: str, end: str, bank: List[str]) -> int: - def dfs(start, t): - if start == end: - nonlocal ans - ans = min(ans, t) - return - for i, x in enumerate(start): - for y in 'ACGT': - if x != y: - nxt = start[:i] + y + start[i + 1 :] - if nxt in s: - s.remove(nxt) - dfs(nxt, t + 1) - - s = set(bank) - ans = inf - dfs(start, 0) - return -1 if ans == inf else ans diff --git a/solution/1300-1399/1306.Jump Game III/README_EN.md b/solution/1300-1399/1306.Jump Game III/README_EN.md index e50adc18433f1..f4964c985d6cf 100644 --- a/solution/1300-1399/1306.Jump Game III/README_EN.md +++ b/solution/1300-1399/1306.Jump Game III/README_EN.md @@ -69,7 +69,17 @@ index 0 -> index 4 -> index 1 -> index 3 -### Solution 1 +### Solution 1: BFS + +We can use BFS to determine whether we can reach the index with a value of $0$. + +Define a queue $q$ to store the currently reachable indices. Initially, enqueue the $start$ index. + +When the queue is not empty, take out the front index $i$ of the queue. If $arr[i] = 0$, return `true`. Otherwise, mark the index $i$ as visited. If $i + arr[i]$ and $i - arr[i]$ are within the array range and have not been visited, enqueue them and continue searching. + +Finally, if the queue is empty, it means that we cannot reach the index with a value of $0$, so return `false`. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the length of the array. diff --git a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README.md b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README.md index 7c2321803bda7..eba987060cd83 100644 --- a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README.md +++ b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README.md @@ -73,9 +73,9 @@ tags: ### 方法一:双指针 -我们定义两个指针 $i$ 和 $j$,分别指向字符串 $s$ 和 $t$ 的首字符。遍历字符串 $t$,当 $s[i] \neq t[j]$ 时,指针 $i$ 后移,直到 $s[i] = t[j]$ 或者 $i$ 到达字符串 $s$ 的末尾。如果 $i$ 到达字符串 $s$ 的末尾,说明 $t$ 中的字符 $t[j]$ 无法在 $s$ 中找到对应的字符,返回 $t$ 中剩余的字符数。否则,将指针 $i$ 和 $j$ 同时后移,继续遍历字符串 $t$。 +我们定义两个指针 $i$ 和 $j$,分别指向字符串 $s$ 和 $t$ 的首字符。遍历字符串 $s$,如果 $s[i] = t[j]$,则将 $j$ 向后移动一位。最终返回 $n - j$,其中 $n$ 是字符串 $t$ 的长度。 -时间复杂度 $(m + n)$,空间复杂度 $O(1)$。其中 $m$ 和 $n$ 分别是字符串 $s$ 和 $t$ 的长度。 +时间复杂度 $(m + n)$,其中 $m$ 和 $n$ 分别是字符串 $s$ 和 $t$ 的长度。空间复杂度 $O(1)$。 @@ -84,14 +84,11 @@ tags: ```python class Solution: def appendCharacters(self, s: str, t: str) -> int: - i, m = 0, len(s) - for j, c in enumerate(t): - while i < m and s[i] != c: - i += 1 - if i == m: - return len(t) - j - i += 1 - return 0 + n, j = len(t), 0 + for c in s: + if j < n and c == t[j]: + j += 1 + return n - j ``` #### Java @@ -99,16 +96,13 @@ class Solution: ```java class Solution { public int appendCharacters(String s, String t) { - int m = s.length(), n = t.length(); - for (int i = 0, j = 0; j < n; ++j) { - while (i < m && s.charAt(i) != t.charAt(j)) { - ++i; - } - if (i++ == m) { - return n - j; + int n = t.length(), j = 0; + for (int i = 0; i < s.length() && j < n; ++i) { + if (s.charAt(i) == t.charAt(j)) { + ++j; } } - return 0; + return n - j; } } ``` @@ -119,16 +113,13 @@ class Solution { class Solution { public: int appendCharacters(string s, string t) { - int m = s.size(), n = t.size(); - for (int i = 0, j = 0; j < n; ++j) { - while (i < m && s[i] != t[j]) { - ++i; - } - if (i++ == m) { - return n - j; + int n = t.length(), j = 0; + for (int i = 0; i < s.size() && j < n; ++i) { + if (s[i] == t[j]) { + ++j; } } - return 0; + return n - j; } }; ``` @@ -137,16 +128,13 @@ public: ```go func appendCharacters(s string, t string) int { - m, n := len(s), len(t) - for i, j := 0, 0; j < n; i, j = i+1, j+1 { - for i < m && s[i] != t[j] { - i++ - } - if i == m { - return n - j + n, j := len(t), 0 + for _, c := range s { + if j < n && byte(c) == t[j] { + j++ } } - return 0 + return n - j } ``` @@ -154,13 +142,12 @@ func appendCharacters(s string, t string) int { ```ts function appendCharacters(s: string, t: string): number { - const n = s.length; let j = 0; - - for (let i = 0; i < n; i++) { - if (s[i] === t[j]) j++; + for (const c of s) { + if (c === t[j]) { + ++j; + } } - return t.length - j; } ``` diff --git a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README_EN.md b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README_EN.md index 1cb8602b98467..b326bfdd3961f 100644 --- a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README_EN.md +++ b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README_EN.md @@ -71,9 +71,9 @@ It can be shown that appending any 4 characters to the end of s will never make ### Solution 1: Two Pointers -We define two pointers $i$ and $j$, pointing to the first characters of strings $s$ and $t$ respectively. We traverse string $t$, when $s[i] \neq t[j]$, we move pointer $i$ forward until $s[i] = t[j]$ or $i$ reaches the end of string $s$. If $i$ reaches the end of string $s$, it means that the character $t[j]$ in $t$ cannot find the corresponding character in $s$, so we return the remaining number of characters in $t$. Otherwise, we move both pointers $i$ and $j$ forward and continue to traverse string $t$. +We define two pointers $i$ and $j$, pointing to the first characters of strings $s$ and $t$ respectively. We iterate through string $s$, if $s[i] = t[j]$, then we move $j$ one step forward. Finally, we return $n - j$, where $n$ is the length of string $t$. -The time complexity is $O(m + n)$, and the space complexity is $O(1)$. Where $m$ and $n$ are the lengths of strings $s$ and $t$ respectively. +The time complexity is $O(m + n)$, where $m$ and $n$ are the lengths of strings $s$ and $t$ respectively. The space complexity is $O(1)$. @@ -82,14 +82,11 @@ The time complexity is $O(m + n)$, and the space complexity is $O(1)$. Where $m$ ```python class Solution: def appendCharacters(self, s: str, t: str) -> int: - i, m = 0, len(s) - for j, c in enumerate(t): - while i < m and s[i] != c: - i += 1 - if i == m: - return len(t) - j - i += 1 - return 0 + n, j = len(t), 0 + for c in s: + if j < n and c == t[j]: + j += 1 + return n - j ``` #### Java @@ -97,16 +94,13 @@ class Solution: ```java class Solution { public int appendCharacters(String s, String t) { - int m = s.length(), n = t.length(); - for (int i = 0, j = 0; j < n; ++j) { - while (i < m && s.charAt(i) != t.charAt(j)) { - ++i; - } - if (i++ == m) { - return n - j; + int n = t.length(), j = 0; + for (int i = 0; i < s.length() && j < n; ++i) { + if (s.charAt(i) == t.charAt(j)) { + ++j; } } - return 0; + return n - j; } } ``` @@ -117,16 +111,13 @@ class Solution { class Solution { public: int appendCharacters(string s, string t) { - int m = s.size(), n = t.size(); - for (int i = 0, j = 0; j < n; ++j) { - while (i < m && s[i] != t[j]) { - ++i; - } - if (i++ == m) { - return n - j; + int n = t.length(), j = 0; + for (int i = 0; i < s.size() && j < n; ++i) { + if (s[i] == t[j]) { + ++j; } } - return 0; + return n - j; } }; ``` @@ -135,16 +126,13 @@ public: ```go func appendCharacters(s string, t string) int { - m, n := len(s), len(t) - for i, j := 0, 0; j < n; i, j = i+1, j+1 { - for i < m && s[i] != t[j] { - i++ - } - if i == m { - return n - j + n, j := len(t), 0 + for _, c := range s { + if j < n && byte(c) == t[j] { + j++ } } - return 0 + return n - j } ``` @@ -152,13 +140,12 @@ func appendCharacters(s string, t string) int { ```ts function appendCharacters(s: string, t: string): number { - const n = s.length; let j = 0; - - for (let i = 0; i < n; i++) { - if (s[i] === t[j]) j++; + for (const c of s) { + if (c === t[j]) { + ++j; + } } - return t.length - j; } ``` diff --git a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.cpp b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.cpp index 7d012b94ef9eb..28b6ac81cfa30 100644 --- a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.cpp +++ b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.cpp @@ -1,15 +1,12 @@ class Solution { public: int appendCharacters(string s, string t) { - int m = s.size(), n = t.size(); - for (int i = 0, j = 0; j < n; ++j) { - while (i < m && s[i] != t[j]) { - ++i; - } - if (i++ == m) { - return n - j; + int n = t.length(), j = 0; + for (int i = 0; i < s.size() && j < n; ++i) { + if (s[i] == t[j]) { + ++j; } } - return 0; + return n - j; } }; \ No newline at end of file diff --git a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.go b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.go index 16f2de6ae56ad..414b336cffa76 100644 --- a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.go +++ b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.go @@ -1,12 +1,9 @@ func appendCharacters(s string, t string) int { - m, n := len(s), len(t) - for i, j := 0, 0; j < n; i, j = i+1, j+1 { - for i < m && s[i] != t[j] { - i++ - } - if i == m { - return n - j + n, j := len(t), 0 + for _, c := range s { + if j < n && byte(c) == t[j] { + j++ } } - return 0 + return n - j } \ No newline at end of file diff --git a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.java b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.java index 8f5e2780ce237..946074d4d9769 100644 --- a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.java +++ b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.java @@ -1,14 +1,11 @@ class Solution { public int appendCharacters(String s, String t) { - int m = s.length(), n = t.length(); - for (int i = 0, j = 0; j < n; ++j) { - while (i < m && s.charAt(i) != t.charAt(j)) { - ++i; - } - if (i++ == m) { - return n - j; + int n = t.length(), j = 0; + for (int i = 0; i < s.length() && j < n; ++i) { + if (s.charAt(i) == t.charAt(j)) { + ++j; } } - return 0; + return n - j; } } \ No newline at end of file diff --git a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.py b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.py index a96c10611b028..8354501c2460c 100644 --- a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.py +++ b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.py @@ -1,10 +1,7 @@ class Solution: def appendCharacters(self, s: str, t: str) -> int: - i, m = 0, len(s) - for j, c in enumerate(t): - while i < m and s[i] != c: - i += 1 - if i == m: - return len(t) - j - i += 1 - return 0 + n, j = len(t), 0 + for c in s: + if j < n and c == t[j]: + j += 1 + return n - j diff --git a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.ts b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.ts index 107cf470d18b1..17cf771e6ff15 100644 --- a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.ts +++ b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.ts @@ -1,10 +1,9 @@ function appendCharacters(s: string, t: string): number { - const n = s.length; let j = 0; - - for (let i = 0; i < n; i++) { - if (s[i] === t[j]) j++; + for (const c of s) { + if (c === t[j]) { + ++j; + } } - return t.length - j; }