@@ -201,43 +201,192 @@ impl Solution {
201
201
#### C#
202
202
203
203
``` cs
204
- // https://leetcode.com/problems/shortest-palindrome/
205
-
206
- using System .Text ;
207
-
208
- public partial class Solution
209
- {
210
- public string ShortestPalindrome (string s )
211
- {
212
- for (var i = s .Length - 1 ; i >= 0 ; -- i )
213
- {
214
- var k = i ;
215
- var j = 0 ;
216
- while (j < k )
217
- {
218
- if (s [j ] == s [k ])
219
- {
220
- ++ j ;
221
- -- k ;
222
- }
223
- else
224
- {
225
- break ;
226
- }
204
+ public class Solution {
205
+ public string ShortestPalindrome (string s ) {
206
+ int baseValue = 131 ;
207
+ int mul = 1 ;
208
+ int mod = (int )1 e 9 + 7 ;
209
+ int prefix = 0 , suffix = 0 ;
210
+ int idx = 0 ;
211
+ int n = s .Length ;
212
+
213
+ for (int i = 0 ; i < n ; ++ i ) {
214
+ int t = s [i ] - 'a' + 1 ;
215
+ prefix = (int )(((long )prefix * baseValue + t ) % mod );
216
+ suffix = (int )((suffix + (long )t * mul ) % mod );
217
+ mul = (int )(((long )mul * baseValue ) % mod );
218
+ if (prefix == suffix ) {
219
+ idx = i + 1 ;
227
220
}
228
- if (j >= k )
229
- {
230
- var sb = new StringBuilder (s .Length * 2 - i - 1 );
231
- for (var l = s .Length - 1 ; l >= i + 1 ; -- l )
232
- {
233
- sb .Append (s [l ]);
234
- }
235
- sb .Append (s );
236
- return sb .ToString ();
221
+ }
222
+
223
+ if (idx == n ) {
224
+ return s ;
225
+ }
226
+
227
+ return new string (s .Substring (idx ).Reverse ().ToArray ()) + s ;
228
+ }
229
+ }
230
+ ```
231
+
232
+ <!-- tabs: end -->
233
+
234
+ <!-- solution: end -->
235
+
236
+ <!-- solution: start -->
237
+
238
+ ### 方法二:KMP 算法
239
+
240
+ 根据题目描述,我们需要将字符串 $s$ 反转,得到字符串 $\textit{rev}$,然后求出字符串 $rev$ 的后缀与字符串 $s$ 的前缀的最长公共部分。我们可以使用 KMP 算法,将字符串 $s$ 与字符串 $rev$ 连接起来,求出其最长前缀与最长后缀的最长公共部分。
241
+
242
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $s$ 的长度。
243
+
244
+ <!-- tabs: start -->
245
+
246
+ #### Python3
247
+
248
+ ``` python
249
+ class Solution :
250
+ def shortestPalindrome (self , s : str ) -> str :
251
+ t = s + " #" + s[::- 1 ] + " $"
252
+ n = len (t)
253
+ next = [0 ] * n
254
+ next [0 ] = - 1
255
+ i, j = 2 , 0
256
+ while i < n:
257
+ if t[i - 1 ] == t[j]:
258
+ j += 1
259
+ next [i] = j
260
+ i += 1
261
+ elif j:
262
+ j = next [j]
263
+ else :
264
+ next [i] = 0
265
+ i += 1
266
+ return s[::- 1 ][: - next [- 1 ]] + s
267
+ ```
268
+
269
+ #### Java
270
+
271
+ ``` java
272
+ class Solution {
273
+ public String shortestPalindrome (String s ) {
274
+ char [] t = (s + " #" + new StringBuilder (s). reverse(). toString() + " $" ). toCharArray();
275
+ int n = t. length();
276
+ int [] next = new int [n];
277
+ next[0 ] = - 1 ;
278
+ for (int i = 2 , j = 0 ; i < n;) {
279
+ if (t[i - 1 ] == t[j]) {
280
+ next[i++ ] = ++ j;
281
+ } else if (j > 0 ) {
282
+ j = next[j];
283
+ } else {
284
+ next[i++ ] = 0 ;
285
+ }
286
+ }
287
+ return new StringBuilder (s. substring(next[n - 1 ])). reverse(). substring(0 , s. length() - next[n - 1 ]) + s;
288
+ }
289
+ }
290
+ ```
291
+
292
+ #### C++
293
+
294
+ ``` cpp
295
+ class Solution {
296
+ public:
297
+ string shortestPalindrome(string s) {
298
+ string t = s + "#" + string(s.rbegin(), s.rend()) + "$";
299
+ int n = t.size();
300
+ int next[ n] ;
301
+ next[ 0] = -1;
302
+ next[ 1] = 0;
303
+ for (int i = 2, j = 0; i < n;) {
304
+ if (t[ i - 1] == t[ j] ) {
305
+ next[ i++] = ++j;
306
+ } else if (j > 0) {
307
+ j = next[ j] ;
308
+ } else {
309
+ next[ i++] = 0;
237
310
}
238
311
}
312
+ return string(s.rbegin(), s.rbegin() + s.size() - next[ n - 1] ) + s;
313
+ }
314
+ };
315
+ ```
316
+
317
+ #### Go
239
318
240
- return string .Empty ;
319
+ ```go
320
+ func shortestPalindrome(s string) string {
321
+ t := s + "#" + reverse(s) + "$"
322
+ n := len(t)
323
+ next := make([]int, n)
324
+ next[0] = -1
325
+ for i, j := 2, 0; i < n; {
326
+ if t[i-1] == t[j] {
327
+ j++
328
+ next[i] = j
329
+ i++
330
+ } else if j > 0 {
331
+ j = next[j]
332
+ } else {
333
+ next[i] = 0
334
+ i++
335
+ }
336
+ }
337
+ return reverse(s)[:len(s)-next[n-1]] + s
338
+ }
339
+
340
+ func reverse(s string) string {
341
+ t := []byte(s)
342
+ for i, j := 0, len(t)-1; i < j; i, j = i+1, j-1 {
343
+ t[i], t[j] = t[j], t[i]
344
+ }
345
+ return string(t)
346
+ }
347
+ ```
348
+
349
+ #### TypeScript
350
+
351
+ ``` ts
352
+ function shortestPalindrome(s : string ): string {
353
+ const rev = s .split (' ' ).reverse ().join (' ' );
354
+ const t = s + ' #' + rev + ' $' ;
355
+ const n = t .length ;
356
+ const next: number [] = Array (n ).fill (0 );
357
+ next [0 ] = - 1 ;
358
+ for (let i = 2 , j = 0 ; i < n ; ) {
359
+ if (t [i - 1 ] === t [j ]) {
360
+ next [i ++ ] = ++ j ;
361
+ } else if (j > 0 ) {
362
+ j = next [j ];
363
+ } else {
364
+ next [i ++ ] = 0 ;
365
+ }
366
+ }
367
+ return rev .slice (0 , - next [n - 1 ]) + s ;
368
+ }
369
+ ```
370
+
371
+ #### C#
372
+
373
+ ``` cs
374
+ public class Solution {
375
+ public string ShortestPalindrome (string s ) {
376
+ char [] t = (s + " #" + new string (s .Reverse ().ToArray ()) + " $" ).ToCharArray ();
377
+ int n = t .Length ;
378
+ int [] next = new int [n ];
379
+ next [0 ] = - 1 ;
380
+ for (int i = 2 , j = 0 ; i < n ;) {
381
+ if (t [i - 1 ] == t [j ]) {
382
+ next [i ++ ] = ++ j ;
383
+ } else if (j > 0 ) {
384
+ j = next [j ];
385
+ } else {
386
+ next [i ++ ] = 0 ;
387
+ }
388
+ }
389
+ return new string (s .Substring (next [n - 1 ]).Reverse ().ToArray ()).Substring (0 , s .Length - next [n - 1 ]) + s ;
241
390
}
242
391
}
243
392
```
0 commit comments