Skip to content

Commit 9f31a94

Browse files
authored
feat: add solutions to lc problem: No.0214 (#3416)
No.0214.Shortest Palindrome
1 parent a7c9dd4 commit 9f31a94

File tree

9 files changed

+506
-100
lines changed

9 files changed

+506
-100
lines changed

solution/0200-0299/0214.Shortest Palindrome/README.md

+183-33
Original file line numberDiff line numberDiff line change
@@ -201,43 +201,193 @@ impl Solution {
201201
#### C#
202202

203203
```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)1e9 + 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;
227220
}
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;
237311
}
238312
}
313+
return string(s.rbegin(), s.rbegin() + s.size() - next[n - 1]) + s;
314+
}
315+
};
316+
```
317+
318+
#### Go
239319
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;
241391
}
242392
}
243393
```

0 commit comments

Comments
 (0)