将单词恢复初始状态所需的最短时间 II(kmp,公共前后缀)

给你一个下标从 0 开始的字符串word 和一个整数k

在每一秒,你必须执行以下操作:

移除word的前k个字符。
word的末尾添加k个任意字符。

注意添加的字符不必和移除的字符相同。但是,必须在每一秒钟都执行两种操作。

返回将word恢复到其初始状态所需的最短时间(该时间必须大于零)。

示例 1:

输入:word = "abacaba", k = 3
输出:2
解释:
第 1 秒,移除 word 的前缀 "aba",并在末尾添加 "bac" 。因此,word 变为 "cababac"。
第 2 秒,移除 word 的前缀 "cab",并在末尾添加 "aba" 。因此,word 变为 "abacaba" 并恢复到始状态。
可以证明,2 秒是 word 恢复到其初始状态所需的最短时间。

示例 2:

输入:word = "abacaba", k = 4
输出:1
解释:
第 1 秒,移除 word 的前缀 "abac",并在末尾添加 "caba" 。因此,word 变为 "abacaba" 并恢复到初始状态。
可以证明,1 秒是 word 恢复到其初始状态所需的最短时间。

示例 3:

输入:word = "abcbabcd", k = 2
输出:4
解释:
每一秒,我们都移除 word 的前 2 个字符,并在 word 末尾添加相同的字符。
4 秒后,word 变为 "abcbabcd" 并恢复到初始状态。
可以证明,4 秒是 word 恢复到其初始状态所需的最短时间。

提示:
1<=word.length<=106
1 <= k <= word.length
word仅由小写英文字母组成。

首先我们先看一个例子:abacaba k=3,
第一次删除:
abacaba
caba---
a------
我们发现删除之后后面填什么不重要,所以我们只需要找到前缀和后缀相同,并且总的字符数-相同前后缀之后可以被k整除就行。
还有一点就是无论如何它都是有答案的。

然后我们发现最主要的就是找到符合条件的公共前后缀,这个就是kmp中的next数组

class Solution {
public:
    int minimumTimeToInitialState(string word, int k) {
        int n=word.size();
        int ne[n+2];
        int res=0;
        int i=0,j=-1;
        int len=n;
        ne[0]=-1;
        while(i<len){
            if(j==-1||word[i]==word[j]){
                i++;
                j++; 
                ne[i]=j;
            }
            else{
                j=ne[j];
            }
        }
        // for(int i=1;i<=n;i++){
        //     cout<<ne[i]<<" ";
        // }
        // cout<<endl;
        int tmp=ne[n];
        if(ne[n]==n-1){
            return 1;
        }
        if(ne[n]==0){
            return n%k==0?n/k:(n/k+1);
        }
        while(!((n-tmp)%k==0)&&tmp){
            tmp=ne[tmp];
            cout<<tmp<<endl;
        }
        return (n-tmp)%k==0?(n-tmp)/k:(n-tmp)/k+1;
    }
};
posted @   lipu123  阅读(26)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示