这就是kmp计算步骤中的第一步骤——计算最长前后串,记录一下思路,网上的教程很多,还是挺复杂的。这是我的思路整理。
首先,本质上是一个dp问题。假设dp[i]表示字符串中,[0,i]区间内的最长前后串。
主要分解成如下步骤,
- 如果dp[i-1]=K,那么说明,[0,i-1]中,前K个和后K个一定是相同的。如果在上图中j位置s[j]==s[i],那么dp[i+1]就可以变成K+1
- 如果不相同,假设dp[j-1]=M,说明s[0:M-1]==s[K-M:K-1],也就是前面K个中,前M个元素=后M个元素,同理,后面K个元素,也存在M这样的后缀。在这种条件下,j从K变到了M位置,如果再相同了,那么dp[i]=dp[j-1]+1
- 重复步骤2,直到s[j]==s[i]为止。
class Solution {
public:
string longestPrefix(string s) {
vector<int> dp(s.size(), 0);
for(int i=1;i<s.size();i++){
int j = i;
while(j-1>=0&&s[i]!=s[dp[j-1]]){
j = dp[j-1];
}
if (j-1<0){
dp[i] = 0;
}
else if (s[i]==s[dp[j-1]]){
dp[i] = dp[j-1]+1;
}
else{
cout<<"error!!"<<endl;
}
//cout<<dp[i]<<endl;
}
return s.substr(0, dp[s.size()-1]);
}
};