https://leetcode.com/problems/sum-of-scores-of-built-strings/
leetcode的hard题目已经开始超纲了,线段树,z函数等等东西层出不穷,真的要好好学习了。
对z函数的考察,记下来备忘。
题目解答
class Solution:
def sumScores(self, s: str) -> int:
def zFunc(s):
z = [0] * len(s)
l, r = 0, 0
for i in range(1, len(s)):
if i <= r and z[i - l] < r - i + 1:
z[i] = z[i - l]
else:
z[i] = max(0, r - i + 1)
while z[i] + i < len(s) and s[z[i]] == s[z[i] + i]:
z[i] += 1
if i + z[i] - 1 > r:
l, r = i, i + z[i] - 1
print(i, l, r)
print(z)
return z
return sum(zFunc(s)) + len(s)
题目分析
首先z函数没什么好说的,记下来就好。
注意,判断是否可以复用前边的结果,是i <= r
而不是i < r
,等于的情况还是要单独判断的,有可能z[r - l]
是0的。
然后说回z函数的算法。其实类似KMP,复用前边的结果,只不过维护最右侧的匹配段,比较难想到,常复习,常思考。
参考:https://oi-wiki.org/string/z-func/
注意仔细过里边的演示,应该比较轻松能明白。
另外,遇到算法题,或者遇到这种不会的算法,不要急着看现成的优雅实现,可以先自己根据思想写个naive版本,程序员的能力,不就是这么训练出来的吗?靠记忆,永远记不完的。