Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions dynamic_programming/longest_palindromic_substring.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# reference :https://www.geeksforgeeks.org/dsa/longest-palindromic-substring/


def longest_palindromic_substring(s: str) -> str:
"""
This function returns longest palindromic substring in a string
using Dynamic Programming.

s : input string
>>> longest_palindromic_substring("babad")
'aba'
>>> longest_palindromic_substring("cbbd")
'bb'
>>> longest_palindromic_substring("a")
'a'
>>> longest_palindromic_substring("ac")
'a'
>>> longest_palindromic_substring("")
''
"""
n = len(s)

dp = [[False for i in range(n)] for j in range(n)]
start = 0
max_length = 1

for i in range(n):
dp[i][i] = True
# for length 2 palindrome check
for i in range(n - 1):
if s[i] == s[i + 1]:
dp[i][i + 1] = True
start = i
max_length = 2

# for length 3 and above
for length in range(3, n + 1):
for i in range(n - length + 1):
j = i + length - 1
if s[i] == s[j] and dp[i + 1][j - 1]:
dp[i][j] = True
start = i
max_length = length

return s[start : start + max_length]


def manacher_algorithm(s: str) -> str:
"""
This function returns the longest palindromic substring in a string
using Manacher's algorithm.

s : input string
t : transformed string
p : array to store length of palindrome radius around each center
c : center of the current rightmost palindrome
r : right edge of the current rightmost palindrome
n : length of transformed string

>>> longest_palindromic_substring("babad")
'aba'
>>> longest_palindromic_substring("cbbd")
'bb'
>>> longest_palindromic_substring("a")
'a'
>>> longest_palindromic_substring("ac")
'a'
>>> longest_palindromic_substring("")
''
"""
t = "^#" + "#".join(s) + "#$"
n = len(t)

p = [0] * n
c = 0
r = 0

for i in range(1, n - 1):
mirror = 2 * c - i
if i < r:
p[i] = min(r - i, p[mirror])
while t[i + (1 + p[i])] == t[i - (1 + p[i])]:
p[i] += 1
if i + p[i] > r:
c = i
r = i + p[i]

max_length = max(p)
max_center = p.index(max_length)
start = (max_center - max_length) // 2
return s[start : start + max_length]


if __name__ == "__main__":
import doctest

doctest.testmod()