Skip to content

Commit 4ddd157

Browse files
committed
feat: add solutions to lc problem: No.0214
No.0214.Shortest Palindrome
1 parent a7c9dd4 commit 4ddd157

File tree

9 files changed

+503
-100
lines changed

9 files changed

+503
-100
lines changed

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

Lines changed: 182 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -201,43 +201,192 @@ 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+
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;
237310
}
238311
}
312+
return string(s.rbegin(), s.rbegin() + s.size() - next[n - 1]) + s;
313+
}
314+
};
315+
```
316+
317+
#### Go
239318
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;
241390
}
242391
}
243392
```

0 commit comments

Comments
 (0)