-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path0005_longest-palindromic-substring.py
93 lines (75 loc) · 2.8 KB
/
0005_longest-palindromic-substring.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# First attempt ->
# Solution based around expanding around center
# class Solution:
# def longestPalindrome(self, s: str) -> str:
# N: int = len(s)
# if N < 2:
# return s
# longest_str: str = s[1]
# longest_len: int = 1
# for i in range(N - 1):
# buff: str = s[i]
# j: int = 1
# k: int = 1
# c: str = s[i]
# # first we check for repeating characters, ie
# # aa, aaa, aaaaa, .....
# while True:
# if i + k >= N or not (s[i + k] == c):
# break
# buff += c
# k += 1
# # then we check for nontrivial palindromes, ie
# # aba, abcba, abcdcba, (as well as abbba)
# while True:
# if i - j < 0 or i + k >= N or not (s[i - j] == s[i + k]):
# break
# buff = s[i - j] + buff + s[i + k]
# j += 1
# k += 1
# if (j + k - 1) > longest_len:
# longest_str = buff
# longest_len = j + k - 1
# return longest_str
# DP approach -> this is somehow slower than my first attempt? wtf?
# class Solution:
# def longestPalindrome(self, s: str) -> str:
# N: int = len(s)
# if N < 2:
# return s
# longest_str: str = s[1]
# longest_len: int = 1
# dp = [[False for _ in range(N)] for _ in range(N)]
# for i in range(N):
# # f(0) case, the bootstrapping rule for the induction/recursion
# dp[i][i] = True
# for j in range(i):
# # The inductive/recursive step
# if (s[i] == s[j]) and (i - j <= 2 or dp[j + 1][i - 1]):
# dp[j][i] = True
# if i - j + 1 > longest_len:
# longest_str = s[j : i + 1]
# longest_len = i - j + 1
# return longest_str
# Naive solution with string preprocessing
# somehow faster then DP??
class Solution:
def longestPalindrome(self, s: str) -> str:
if len(s) < 2:
return s
s = "#" + "#".join(s) + "#"
N: int = len(s)
longest_str: str = s[1]
longest_len: int = 1
for i in range(1, N - 1):
j: int = 1
while i - j >= 0 and i + j < N and s[i - j] == s[i + j]:
j += 1
if (j - 1) > longest_len:
longest_len = j - 1
start = (i - longest_len) // 2
longest_str = s[2 * start : (start + longest_len) * 2 + 1]
# Optimalization -> skip if we cannot construct larger palindromes
if longest_len >= (N - 1 - i):
break
return longest_str.replace("#", "")