Skip to content

Commit b9a754c

Browse files
authored
feat: add solutions to lc problem: No.467 (doocs#3056)
No.0467.Unique Substrings in Wraparound String
1 parent 5a41329 commit b9a754c

File tree

8 files changed

+179
-199
lines changed

8 files changed

+179
-199
lines changed

solution/0400-0499/0467.Unique Substrings in Wraparound String/README.md

Lines changed: 60 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -68,52 +68,48 @@ tags:
6868

6969
### 方法一:动态规划
7070

71-
不妨设 `dp[α]` 表示 p 中以字符 α 结尾且在 s 中的子串的最大长度,将 dp 求和可以得到最终结果
71+
我们不妨定义一个长度为 $26$ 的数组 $f$,其中 $f[i]$ 表示以第 $i$ 个字符结尾的最长连续子串的长度。那么答案就是 $f$ 中所有元素的和
7272

73-
时间复杂度 $O(n)$,其中 $n$ 表示字符串 p 的长度
73+
我们定义一个变量 $k$,表示以当前字符结尾的最长连续子串的长度。遍历字符串 $s$,对于每个字符 $c$,如果 $c$ 和前一个字符 $s[i - 1]$ 之间的差值为 $1$,那么 $k$ 就加 $1$,否则 $k$ 重置为 $1$。然后更新 $f[c]$ 为 $f[c]$ 和 $k$ 的较大值
7474

75-
> 成为子串的一个标准,需要是连续的,`a``c` 之间少了一个 `b`,所以不能算一个子字符串。
75+
最后返回 $f$ 中所有元素的和即可。
76+
77+
时间复杂度 $O(n)$,其中 $n$ 是字符串 $s$ 的长度。空间复杂度 $O(|\Sigma|)$,其中 $\Sigma$ 是字符集,这里是小写字母集合。
7678

7779
<!-- tabs:start -->
7880

7981
#### Python3
8082

8183
```python
8284
class Solution:
83-
def findSubstringInWraproundString(self, p: str) -> int:
84-
dp = [0] * 26
85+
def findSubstringInWraproundString(self, s: str) -> int:
86+
f = defaultdict(int)
8587
k = 0
86-
for i, c in enumerate(p):
87-
if i and (ord(c) - ord(p[i - 1])) % 26 == 1:
88+
for i, c in enumerate(s):
89+
if i and (ord(c) - ord(s[i - 1])) % 26 == 1:
8890
k += 1
8991
else:
9092
k = 1
91-
idx = ord(c) - ord('a')
92-
dp[idx] = max(dp[idx], k)
93-
return sum(dp)
93+
f[c] = max(f[c], k)
94+
return sum(f.values())
9495
```
9596

9697
#### Java
9798

9899
```java
99100
class Solution {
100-
public int findSubstringInWraproundString(String p) {
101-
int[] dp = new int[26];
102-
int k = 0;
103-
for (int i = 0; i < p.length(); ++i) {
104-
char c = p.charAt(i);
105-
if (i > 0 && (c - p.charAt(i - 1) + 26) % 26 == 1) {
101+
public int findSubstringInWraproundString(String s) {
102+
int[] f = new int[26];
103+
int n = s.length();
104+
for (int i = 0, k = 0; i < n; ++i) {
105+
if (i > 0 && (s.charAt(i) - s.charAt(i - 1) + 26) % 26 == 1) {
106106
++k;
107107
} else {
108108
k = 1;
109109
}
110-
dp[c - 'a'] = Math.max(dp[c - 'a'], k);
111-
}
112-
int ans = 0;
113-
for (int v : dp) {
114-
ans += v;
110+
f[s.charAt(i) - 'a'] = Math.max(f[s.charAt(i) - 'a'], k);
115111
}
116-
return ans;
112+
return Arrays.stream(f).sum();
117113
}
118114
}
119115
```
@@ -123,88 +119,84 @@ class Solution {
123119
```cpp
124120
class Solution {
125121
public:
126-
int findSubstringInWraproundString(string p) {
127-
vector<int> dp(26);
128-
int k = 0;
129-
for (int i = 0; i < p.size(); ++i) {
130-
char c = p[i];
131-
if (i && (c - p[i - 1] + 26) % 26 == 1)
122+
int findSubstringInWraproundString(string s) {
123+
int f[26]{};
124+
int n = s.length();
125+
for (int i = 0, k = 0; i < n; ++i) {
126+
if (i && (s[i] - s[i - 1] + 26) % 26 == 1) {
132127
++k;
133-
else
128+
} else {
134129
k = 1;
135-
dp[c - 'a'] = max(dp[c - 'a'], k);
130+
}
131+
f[s[i] - 'a'] = max(f[s[i] - 'a'], k);
136132
}
137-
int ans = 0;
138-
for (int& v : dp) ans += v;
139-
return ans;
133+
return accumulate(begin(f), end(f), 0);
140134
}
141135
};
142136
```
143137
144138
#### Go
145139
146140
```go
147-
func findSubstringInWraproundString(p string) int {
148-
dp := make([]int, 26)
141+
func findSubstringInWraproundString(s string) (ans int) {
142+
f := [26]int{}
149143
k := 0
150-
for i := range p {
151-
c := p[i]
152-
if i > 0 && (c-p[i-1]+26)%26 == 1 {
144+
for i := range s {
145+
if i > 0 && (s[i]-s[i-1]+26)%26 == 1 {
153146
k++
154147
} else {
155148
k = 1
156149
}
157-
dp[c-'a'] = max(dp[c-'a'], k)
150+
f[s[i]-'a'] = max(f[s[i]-'a'], k)
158151
}
159-
ans := 0
160-
for _, v := range dp {
161-
ans += v
152+
for _, x := range f {
153+
ans += x
162154
}
163-
return ans
155+
return
164156
}
165157
```
166158

167159
#### TypeScript
168160

169161
```ts
170-
function findSubstringInWraproundString(p: string): number {
171-
const n = p.length;
172-
const dp = new Array(26).fill(0);
173-
let cur = 1;
174-
dp[p.charCodeAt(0) - 'a'.charCodeAt(0)] = 1;
175-
for (let i = 1; i < n; i++) {
176-
if ((p.charCodeAt(i) - p.charCodeAt(i - 1) + 25) % 26 == 0) {
177-
cur++;
162+
function findSubstringInWraproundString(s: string): number {
163+
const idx = (c: string): number => c.charCodeAt(0) - 97;
164+
const f: number[] = Array(26).fill(0);
165+
const n = s.length;
166+
for (let i = 0, k = 0; i < n; ++i) {
167+
const j = idx(s[i]);
168+
if (i && (j - idx(s[i - 1]) + 26) % 26 === 1) {
169+
++k;
178170
} else {
179-
cur = 1;
171+
k = 1;
180172
}
181-
const index = p.charCodeAt(i) - 'a'.charCodeAt(0);
182-
dp[index] = Math.max(dp[index], cur);
173+
f[j] = Math.max(f[j], k);
183174
}
184-
return dp.reduce((r, v) => r + v);
175+
return f.reduce((acc, cur) => acc + cur, 0);
185176
}
186177
```
187178

188179
#### Rust
189180

190181
```rust
191182
impl Solution {
192-
pub fn find_substring_in_wrapround_string(p: String) -> i32 {
193-
let n = p.len();
194-
let p = p.as_bytes();
195-
let mut dp = [0; 26];
196-
let mut cur = 1;
197-
dp[(p[0] - b'a') as usize] = 1;
198-
for i in 1..n {
199-
if (p[i] - p[i - 1] + 25) % 26 == 0 {
200-
cur += 1;
183+
pub fn find_substring_in_wrapround_string(s: String) -> i32 {
184+
let idx = |c: u8| -> usize { (c - b'a') as usize };
185+
let mut f = vec![0; 26];
186+
let n = s.len();
187+
let s = s.as_bytes();
188+
let mut k = 0;
189+
for i in 0..n {
190+
let j = idx(s[i]);
191+
if i > 0 && ((j as i32) - (idx(s[i - 1]) as i32) + 26) % 26 == 1 {
192+
k += 1;
201193
} else {
202-
cur = 1;
194+
k = 1;
203195
}
204-
let index = (p[i] - b'a') as usize;
205-
dp[index] = dp[index].max(cur);
196+
f[j] = f[j].max(k);
206197
}
207-
dp.into_iter().sum()
198+
199+
f.iter().sum()
208200
}
209201
}
210202
```

0 commit comments

Comments
 (0)