@@ -201,43 +201,193 @@ 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
+ String rev = new StringBuilder (s). reverse(). toString();
275
+ char [] t = (s + " #" + rev + " $" ). toCharArray();
276
+ int n = t. length;
277
+ int [] next = new int [n];
278
+ next[0 ] = - 1 ;
279
+ for (int i = 2 , j = 0 ; i < n;) {
280
+ if (t[i - 1 ] == t[j]) {
281
+ next[i++ ] = ++ j;
282
+ } else if (j > 0 ) {
283
+ j = next[j];
284
+ } else {
285
+ next[i++ ] = 0 ;
286
+ }
287
+ }
288
+ return rev. substring(0 , s. length() - next[n - 1 ]) + s;
289
+ }
290
+ }
291
+ ```
292
+
293
+ #### C++
294
+
295
+ ``` cpp
296
+ class Solution {
297
+ public:
298
+ string shortestPalindrome(string s) {
299
+ string t = s + "#" + string(s.rbegin(), s.rend()) + "$";
300
+ int n = t.size();
301
+ int next[ n] ;
302
+ next[ 0] = -1;
303
+ next[ 1] = 0;
304
+ for (int i = 2, j = 0; i < n;) {
305
+ if (t[ i - 1] == t[ j] ) {
306
+ next[ i++] = ++j;
307
+ } else if (j > 0) {
308
+ j = next[ j] ;
309
+ } else {
310
+ next[ i++] = 0;
237
311
}
238
312
}
313
+ return string(s.rbegin(), s.rbegin() + s.size() - next[ n - 1] ) + s;
314
+ }
315
+ };
316
+ ```
317
+
318
+ #### Go
239
319
240
- return string .Empty ;
320
+ ```go
321
+ func shortestPalindrome(s string) string {
322
+ t := s + "#" + reverse(s) + "$"
323
+ n := len(t)
324
+ next := make([]int, n)
325
+ next[0] = -1
326
+ for i, j := 2, 0; i < n; {
327
+ if t[i-1] == t[j] {
328
+ j++
329
+ next[i] = j
330
+ i++
331
+ } else if j > 0 {
332
+ j = next[j]
333
+ } else {
334
+ next[i] = 0
335
+ i++
336
+ }
337
+ }
338
+ return reverse(s)[:len(s)-next[n-1]] + s
339
+ }
340
+
341
+ func reverse(s string) string {
342
+ t := []byte(s)
343
+ for i, j := 0, len(t)-1; i < j; i, j = i+1, j-1 {
344
+ t[i], t[j] = t[j], t[i]
345
+ }
346
+ return string(t)
347
+ }
348
+ ```
349
+
350
+ #### TypeScript
351
+
352
+ ``` ts
353
+ function shortestPalindrome(s : string ): string {
354
+ const rev = s .split (' ' ).reverse ().join (' ' );
355
+ const t = s + ' #' + rev + ' $' ;
356
+ const n = t .length ;
357
+ const next: number [] = Array (n ).fill (0 );
358
+ next [0 ] = - 1 ;
359
+ for (let i = 2 , j = 0 ; i < n ; ) {
360
+ if (t [i - 1 ] === t [j ]) {
361
+ next [i ++ ] = ++ j ;
362
+ } else if (j > 0 ) {
363
+ j = next [j ];
364
+ } else {
365
+ next [i ++ ] = 0 ;
366
+ }
367
+ }
368
+ return rev .slice (0 , - next [n - 1 ]) + s ;
369
+ }
370
+ ```
371
+
372
+ #### C#
373
+
374
+ ``` cs
375
+ public class Solution {
376
+ public string ShortestPalindrome (string s ) {
377
+ char [] t = (s + " #" + new string (s .Reverse ().ToArray ()) + " $" ).ToCharArray ();
378
+ int n = t .Length ;
379
+ int [] next = new int [n ];
380
+ next [0 ] = - 1 ;
381
+ for (int i = 2 , j = 0 ; i < n ;) {
382
+ if (t [i - 1 ] == t [j ]) {
383
+ next [i ++ ] = ++ j ;
384
+ } else if (j > 0 ) {
385
+ j = next [j ];
386
+ } else {
387
+ next [i ++ ] = 0 ;
388
+ }
389
+ }
390
+ return new string (s .Substring (next [n - 1 ]).Reverse ().ToArray ()).Substring (0 , s .Length - next [n - 1 ]) + s ;
241
391
}
242
392
}
243
393
```
0 commit comments