Skip to content

Commit e6f1dbe

Browse files
authored
Manacher's algorithms - in Python (#575)
* add_integer_divide * add_integer_divide * add_integer_divide * add_integer_divide * README updated * Manacher's algorithm * Manacher's algorithm * add Manacher's algorithm * with more snack test case * more snack cases for testing files * change the name of function `longestPalindrome` to `longest_palindrome` * test changed because the name of function changed
1 parent db43efd commit e6f1dbe

File tree

4 files changed

+71
-5
lines changed

4 files changed

+71
-5
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,10 @@ If you want to uninstall algorithms, it is as simple as:
329329
- [longest_common_prefix](algorithms/strings/longest_common_prefix.py)
330330
- [rotate](algorithms/strings/rotate.py)
331331
- [first_unique_char](algorithms/strings/first_unique_char.py)
332-
- [repeat_substring](algorithms/strings/repeat_substring.py)
333-
- [atbash_cipher](algorithms/strings/atbash_cipher.py)
334-
- [knuth_morris_pratt](algorithms/strings/knuth_morris_pratt.py)
332+
- [repeat_substring](algorithms/strings/repeat_substring.py)
333+
- [atbash_cipher](algorithms/strings/atbash_cipher.py)
334+
- [longest_palindromic_substring](algorithms/strings/longest_palindromic_substring.py)
335+
- [knuth_morris_pratt](algorithms/strings/knuth_morris_pratt.py)
335336
- [tree](algorithms/tree)
336337
- [bst](algorithms/tree/bst)
337338
- [array_to_bst](algorithms/tree/bst/array_to_bst.py)

algorithms/strings/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@
3535
from .first_unique_char import *
3636
from .repeat_substring import *
3737
from .atbash_cipher import *
38+
from .longest_palindromic_substring import *
3839
from .knuth_morris_pratt import *
39-
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'''
2+
Given string s, find the longest palindromic substring.
3+
4+
Example1:
5+
6+
* input: "dasdasdasdasdasdadsa"
7+
* output: "asdadsa"
8+
9+
Example2:
10+
11+
* input: "acdbbdaa"
12+
* output: "dbbd"
13+
14+
Manacher's algorithm
15+
16+
'''
17+
18+
def longest_palindrome(s):
19+
if len(s) < 2:
20+
return s
21+
22+
n_str = '#' + '#'.join(s) + '#'
23+
p = [0] * len(n_str)
24+
mx, loc = 0, 0
25+
index, maxlen = 0, 0
26+
for i in range(len(n_str)):
27+
if i < mx and 2 * loc - i < len(n_str):
28+
p[i] = min(mx - i, p[2 * loc - i])
29+
else:
30+
p[i] = 1
31+
32+
while p[i] + i < len(n_str) and i - p[i] >= 0 and n_str[
33+
i - p[i]] == n_str[i + p[i]]:
34+
p[i] += 1
35+
36+
if i + p[i] > mx:
37+
mx = i + p[i]
38+
loc = i
39+
40+
if p[i] > maxlen:
41+
index = i
42+
maxlen = p[i]
43+
s = n_str[index - p[index] + 1:index + p[index]]
44+
return s.replace('#', '')

tests/test_strings.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
first_unique_char,
3939
repeat_substring,
4040
atbash,
41+
longest_palindrome,
4142
knuth_morris_pratt
4243
)
4344

@@ -527,24 +528,44 @@ class TestAtbashCipher(unittest.TestCase):
527528
Arguments:
528529
unittest {[type]} -- [description]
529530
"""
530-
531+
531532
def test_atbash_cipher(self):
532533
self.assertEqual("zyxwvutsrqponml", atbash("abcdefghijklmno"))
533534
self.assertEqual("KbgslM", atbash("PythoN"))
534535
self.assertEqual("AttaCK at DawN", atbash("ZggzXP zg WzdM"))
535536
self.assertEqual("ZggzXP zg WzdM", atbash("AttaCK at DawN"))
537+
538+
539+
540+
class TestLongestPalindromicSubstring(unittest.TestCase):
541+
"""[summary]
542+
Test for the file longest_palindromic_substring.py
543+
544+
Arguments:
545+
unittest {[type]} -- [description]
546+
"""
547+
548+
def test_longest_palindromic_substring(self):
549+
self.assertEqual("bb", longest_palindrome("cbbd"))
550+
self.assertEqual("abba", longest_palindrome("abba"))
551+
self.assertEqual("asdadsa", longest_palindrome("dasdasdasdasdasdadsa"))
552+
self.assertEqual("abba", longest_palindrome("cabba"))
553+
536554

537555
class TestKnuthMorrisPratt(unittest.TestCase):
538556
"""[summary]
539557
Test for the file knuth_morris_pratt.py
540558
559+
541560
Arguments:
542561
unittest {[type]} -- [description]
543562
"""
563+
544564
def test_knuth_morris_pratt(self):
545565
self.assertEqual([0, 1, 2, 3, 4], knuth_morris_pratt("aaaaaaa", "aaa"))
546566
self.assertEqual([0, 4], knuth_morris_pratt("abcdabc", "abc"))
547567
self.assertEqual([], knuth_morris_pratt("aabcdaab", "aba"))
548568

569+
549570
if __name__ == "__main__":
550571
unittest.main()

0 commit comments

Comments
 (0)