Challenge - Gamma 2011 - CountPalindromicSlices
def solution(S):
result = 0
N = len(S)
MAX_RES = 100000000
# 单个s,为palindromic的中间元素(奇数)
for i,s in enumerate(S[1:-1]):
search_i1, search_i2 = i, i+2
while search_i1>=0 and search_i2<=N-1:
if S[search_i1]==S[search_i2]:
result += 1
if result > MAX_RES:
return -1
search_i1 -= 1
search_i2 += 1
else:
break
# 连续两个s,为palindromic的中间元素(偶数)
for i, s in enumerate(S[:-1]):
search_i1, search_i2 = i, i+1
while search_i1>=0 and search_i2<=N-1:
if S[search_i1]==S[search_i2]:
result += 1
if result > MAX_RES:
return -1
search_i1 -= 1
search_i2 += 1
else:
break
return result
可以看到,虽然Correctness可以达到100%,但是Performance并不能符合题目要求的Efficiency,目前算法的时间复杂度是O(N**2)。
稍微上网搜索了下,本题还算是比较经典的回文数的题了,Leetcode上也有。而这道题有一个复杂度为O(n)的马拉车解法(Manacher Algorithm),是1975年由Manacher发明的。知乎上有一个专门的帖子,各路大神从各个角度来尝试讲清楚这个算法,相信总有一款适合你:www.zhihu.com/question/37…
而我主要是看了答案中的这一篇看懂的:
- 作者:看图学
- 链接:www.zhihu.com/question/37…
具体Python实现如下:
def solution(S):
T = '#'.join('^{}$'.format(S))
# T = s
P = [0] * len(T)
R, C = 0, 0
for i in range(1,len(T) - 1):
if i < R:
P[i] = min(P[2 * C - i], R - i)
while T[i+(P[i]+1)] == T[i-(P[i]+1)]:
P[i] += 1
if i + P[i] > R:
R, C = i + P[i], i
# print(T)
# print(P)
result = sum([p//2 for p in P if p>=2])
return result if result<=100000000 else -1
Challenge - Delta 2011 - MinAbsSum
本题也是Lessons中出现过的题目,是Lessons17 - Dynamic Programming这一章节的,之前在这篇文章中也讲过解题思路,就不再赘述了:juejin.cn/post/722303…