- [Leetcode 3031. Minimum Time to Revert Word to Initial State II](#Leetcode 3031. Minimum Time to Revert Word to Initial State II)
- [1. 解题思路](#1. 解题思路)
- [2. 代码实现](#2. 代码实现)
1. 解题思路
这一题就是一个z算法的题目,算是比较套路的题目了。
关于z算法,之前我们已经写过一个博客(经典算法:Z算法(z algorithm))对这个经典算法本身进行了一下介绍,这里就不展开了,有兴趣的读者可以自行跳转去看一下,或者网上随便其他找一个介绍文章也可以,挺常见的一个算法了。
因此,我们就只看一下z算法是如何应用到这道题目就行了。显然,由于每次移除前k个字符,然后再最后补充k个字符,因此,如果存在某次移除k个字符之后,剩余的子串与原始字符串的开头部分完全一致,那么,我们只需要在后续进行余留的字符补充即可。
而如果知道删除完一轮都无法找到任何字符它的后续子串恰好为原始字符串开头的部分,那么我们也没有关系,总可以删完重排的。
因此,我们要做的就是求取每一个位置的后续子串与原始子串的最长公共头部序列,而这就是z算法要做的事情。
综上,我们先调用一次z算法之后用一个while循环遍历一边即可得到最终答案。
2. 代码实现
给出python代码实现如下:
python
def z_algorithm(s):
n = len(s)
z = [0 for _ in range(n)]
l, r = -1, -1
for i in range(1, n):
if i > r:
l, r = i, i
while r < n and s[r-l] == s[r]:
r += 1
z[i] = r-l
r -= 1
else:
k = i - l
if z[k] < r - i + 1:
z[i] = z[k]
else:
l = i
while r < n and s[r-l] == s[r]:
r += 1
z[i] = r-l
r -= 1
z[0] = n
return z
class Solution:
def minimumTimeToInitialState(self, word: str, k: int) -> int:
z = z_algorithm(word)
ans, idx, n = 0, 0, len(word)
while True:
idx += k
ans += 1
if idx >= n or z[idx] == n-idx:
break
return ans
提交代码评测得到:耗时538ms,占用内存21.2MB。