-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdailycoding046.py
82 lines (63 loc) · 2.37 KB
/
dailycoding046.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
"""
This problem was asked by Amazon.
Given a string, find the longest palindromic contiguous substring.
If there are more than one with the maximum length, return any one.
For example, the longest palindromic substring of "aabcdcb" is "bcdcb".
The longest palindromic substring of "bananas" is "anana".
solution:
1) Use a recursive approach. The base case is if the string is empty
or if it already a palindrome which checks in O(N) time. Otherwise try
all possible starting and ending positions. There are N choose 2 possible
starting and ending solutions excluding trivial solutions (choosing
individual characters as palindromes) and each function call does O(N)
in is_palindrome. Runs in O(N^3) time, constant space
2) Use an expanding window approach. Palindromes have mirror symmetry so expand
a window about every pivot point in the string and keep track of the max
palindrome. There are 2N-1 pivots since between chars and chars can be pivots
in a palindrome, and expanding a window takes O(N), so runs in O(N^2) time,
constant space.
"""
def is_palindrome(string):
return string == string[::-1]
def palindromic_substr(string):
"""Recursive method **very slow**
"""
if not string or is_palindrome(string):
return string
s1 = palindromic_substr(string[1:])
s2 = palindromic_substr(string[:-1])
return s1 if len(s1) >= len(s2) else s2
def expand_win(string, left, right):
while left >= 0 and right < len(string) and (string[left] == string[right]):
left -= 1
right += 1
return right - left - 1
def longest_pal_dp(string):
"""Expanding window approach
"""
start, end = 0, 0
for i in range(len(string)):
# expand from between chars
len1 = expand_win(string, i, i + 1)
# expand about char
len2 = expand_win(string, i, i)
max_len = max(len1, len2)
if max_len > end - start:
start = i - (max_len - 1) // 2
end = i + max_len // 2
return string[start: end + 1]
def main():
tests = {
"aabcdcb": "bcdcb",
"google": "goog",
"banana": "anana",
"apple": "pp",
"a": "a",
"racecar": "racecar"
}
if all(longest_pal_dp(k) == tests[k] for k in tests):
print("Passed")
else:
print("Failed")
if __name__ == '__main__':
main()