@@ -68,52 +68,48 @@ tags:
68
68
69
69
### 方法一:动态规划
70
70
71
- 不妨设 ` dp[α] ` 表示 p 中以字符 α 结尾且在 s 中的子串的最大长度,将 dp 求和可以得到最终结果 。
71
+ 我们不妨定义一个长度为 $26$ 的数组 $f$,其中 $f [ i ] $ 表示以第 $i$ 个字符结尾的最长连续子串的长度。那么答案就是 $f$ 中所有元素的和 。
72
72
73
- 时间复杂度 $O(n)$,其中 $n$ 表示字符串 p 的长度 。
73
+ 我们定义一个变量 $k$,表示以当前字符结尾的最长连续子串的长度。遍历字符串 $s$,对于每个字符 $c$,如果 $c$ 和前一个字符 $s [ i - 1 ] $ 之间的差值为 $1$,那么 $k$ 就加 $1$,否则 $k$ 重置为 $1$。然后更新 $f [ c ] $ 为 $f [ c ] $ 和 $k$ 的较大值 。
74
74
75
- > 成为子串的一个标准,需要是连续的,` a ` 与 ` c ` 之间少了一个 ` b ` ,所以不能算一个子字符串。
75
+ 最后返回 $f$ 中所有元素的和即可。
76
+
77
+ 时间复杂度 $O(n)$,其中 $n$ 是字符串 $s$ 的长度。空间复杂度 $O(|\Sigma|)$,其中 $\Sigma$ 是字符集,这里是小写字母集合。
76
78
77
79
<!-- tabs:start -->
78
80
79
81
#### Python3
80
82
81
83
``` python
82
84
class Solution :
83
- def findSubstringInWraproundString (self , p : str ) -> int :
84
- dp = [ 0 ] * 26
85
+ def findSubstringInWraproundString (self , s : str ) -> int :
86
+ f = defaultdict( int )
85
87
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 :
88
90
k += 1
89
91
else :
90
92
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())
94
95
```
95
96
96
97
#### Java
97
98
98
99
``` java
99
100
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 ) {
106
106
++ k;
107
107
} else {
108
108
k = 1 ;
109
109
}
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);
115
111
}
116
- return ans ;
112
+ return Arrays . stream(f) . sum() ;
117
113
}
118
114
}
119
115
```
@@ -123,88 +119,84 @@ class Solution {
123
119
``` cpp
124
120
class Solution {
125
121
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) {
132
127
++k;
133
- else
128
+ } else {
134
129
k = 1;
135
- dp[ c - 'a'] = max(dp[ c - 'a'] , k);
130
+ }
131
+ f[ s[ i] - 'a'] = max(f[ s[ i] - 'a'] , k);
136
132
}
137
- int ans = 0;
138
- for (int& v : dp) ans += v;
139
- return ans;
133
+ return accumulate(begin(f), end(f), 0);
140
134
}
141
135
};
142
136
```
143
137
144
138
#### Go
145
139
146
140
```go
147
- func findSubstringInWraproundString(p string) int {
148
- dp := make([ ]int, 26)
141
+ func findSubstringInWraproundString(s string) (ans int) {
142
+ f := [26 ]int{}
149
143
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 {
153
146
k++
154
147
} else {
155
148
k = 1
156
149
}
157
- dp[c -'a'] = max(dp[c -'a'], k)
150
+ f[s[i] -'a'] = max(f[s[i] -'a'], k)
158
151
}
159
- ans := 0
160
- for _, v := range dp {
161
- ans += v
152
+ for _, x := range f {
153
+ ans += x
162
154
}
163
- return ans
155
+ return
164
156
}
165
157
```
166
158
167
159
#### TypeScript
168
160
169
161
``` 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 ;
178
170
} else {
179
- cur = 1 ;
171
+ k = 1 ;
180
172
}
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 );
183
174
}
184
- return dp .reduce ((r , v ) => r + v );
175
+ return f .reduce ((acc , cur ) => acc + cur , 0 );
185
176
}
186
177
```
187
178
188
179
#### Rust
189
180
190
181
``` rust
191
182
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 ;
201
193
} else {
202
- cur = 1 ;
194
+ k = 1 ;
203
195
}
204
- let index = (p [i ] - b 'a' ) as usize ;
205
- dp [index ] = dp [index ]. max (cur );
196
+ f [j ] = f [j ]. max (k );
206
197
}
207
- dp . into_iter (). sum ()
198
+
199
+ f . iter (). sum ()
208
200
}
209
201
}
210
202
```
0 commit comments