Skip to content
Merged
Show file tree
Hide file tree
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
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,10 @@ If you want to uninstall algorithms, it is as simple as:
- [longest_common_prefix](algorithms/strings/longest_common_prefix.py)
- [rotate](algorithms/strings/rotate.py)
- [first_unique_char](algorithms/strings/first_unique_char.py)
- [repeat_substring](algorithms/strings/repeat_substring.py)
- [atbash_cipher](algorithms/strings/atbash_cipher.py)
- [knuth_morris_pratt](algorithms/strings/knuth_morris_pratt.py)
- [repeat_substring](algorithms/strings/repeat_substring.py)
- [atbash_cipher](algorithms/strings/atbash_cipher.py)
- [longest_palindromic_substring](algorithms/strings/longest_palindromic_substring.py)
- [knuth_morris_pratt](algorithms/strings/knuth_morris_pratt.py)
- [tree](algorithms/tree)
- [bst](algorithms/tree/bst)
- [array_to_bst](algorithms/tree/bst/array_to_bst.py)
Expand Down
2 changes: 1 addition & 1 deletion algorithms/strings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@
from .first_unique_char import *
from .repeat_substring import *
from .atbash_cipher import *
from .longest_palindromic_substring import *
from .knuth_morris_pratt import *

44 changes: 44 additions & 0 deletions algorithms/strings/longest_palindromic_substring.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'''
Given string s, find the longest palindromic substring.

Example1:

* input: "dasdasdasdasdasdadsa"
* output: "asdadsa"

Example2:

* input: "acdbbdaa"
* output: "dbbd"

Manacher's algorithm

'''

def longest_palindrome(s):
if len(s) < 2:
return s

n_str = '#' + '#'.join(s) + '#'
p = [0] * len(n_str)
mx, loc = 0, 0
index, maxlen = 0, 0
for i in range(len(n_str)):
if i < mx and 2 * loc - i < len(n_str):
p[i] = min(mx - i, p[2 * loc - i])
else:
p[i] = 1

while p[i] + i < len(n_str) and i - p[i] >= 0 and n_str[
i - p[i]] == n_str[i + p[i]]:
p[i] += 1

if i + p[i] > mx:
mx = i + p[i]
loc = i

if p[i] > maxlen:
index = i
maxlen = p[i]
s = n_str[index - p[index] + 1:index + p[index]]
return s.replace('#', '')
23 changes: 22 additions & 1 deletion tests/test_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
first_unique_char,
repeat_substring,
atbash,
longest_palindrome,
knuth_morris_pratt
)

Expand Down Expand Up @@ -527,24 +528,44 @@ class TestAtbashCipher(unittest.TestCase):
Arguments:
unittest {[type]} -- [description]
"""

def test_atbash_cipher(self):
self.assertEqual("zyxwvutsrqponml", atbash("abcdefghijklmno"))
self.assertEqual("KbgslM", atbash("PythoN"))
self.assertEqual("AttaCK at DawN", atbash("ZggzXP zg WzdM"))
self.assertEqual("ZggzXP zg WzdM", atbash("AttaCK at DawN"))



class TestLongestPalindromicSubstring(unittest.TestCase):
"""[summary]
Test for the file longest_palindromic_substring.py

Arguments:
unittest {[type]} -- [description]
"""

def test_longest_palindromic_substring(self):
self.assertEqual("bb", longest_palindrome("cbbd"))
self.assertEqual("abba", longest_palindrome("abba"))
self.assertEqual("asdadsa", longest_palindrome("dasdasdasdasdasdadsa"))
self.assertEqual("abba", longest_palindrome("cabba"))


class TestKnuthMorrisPratt(unittest.TestCase):
"""[summary]
Test for the file knuth_morris_pratt.py


Arguments:
unittest {[type]} -- [description]
"""

def test_knuth_morris_pratt(self):
self.assertEqual([0, 1, 2, 3, 4], knuth_morris_pratt("aaaaaaa", "aaa"))
self.assertEqual([0, 4], knuth_morris_pratt("abcdabc", "abc"))
self.assertEqual([], knuth_morris_pratt("aabcdaab", "aba"))


if __name__ == "__main__":
unittest.main()