OR56. 重复词
描述
对于两个字符串B和C,我们定义BC为将C接在B的后面形成的新串。一个字符串P是串A的前缀,当且仅当存在B使得A=PB,当然B可以为空串。若P!=A,则我们称P为A的真前缀。现在定义重复词。串Q是串A的重复词当且仅当Q是A的真前缀,且A是QQ的前缀。而A的最长重复词则是A的重复词中最长的一个,或者空串(当A没有任何重复串时)。如ababab的最长重复词是abab;abc的最长重复词是空串。
给定一个串s(由字母组成),及它的长度n(1≤n≤100000),请返回s的所有前缀的最长重复词的长度之和(空串长度为0)。
8,"babababa"
返回:24
C++ 解法, 执行用时: 6ms, 内存消耗: 668KB, 提交时间: 2021-09-14
class Periods { public: long long getLongest(int n, string s) { // write code here long long res = 0; if(s.length() == 0) return res; const char*p = s.c_str(); bool flag[100005]; memset(flag, false, sizeof(flag)); int lastindex = n; int coun = 1; for(int i = n -1; i >= 1; i--) { coun = 1; if(p[i] == p[0]) { res += i; int tmp = 1; int k = i+1; while(k<n && tmp <i) { if(p[tmp]== p[k]) { if( p[k] != p[0] && !flag[k] ) { flag[k] = true; res+= i; } tmp++; k++; } if(p[tmp]!= p[k]) break; } } } return res; } };
C++ 解法, 执行用时: 8ms, 内存消耗: 656KB, 提交时间: 2022-02-13
class Periods { public: long long getLongest(int n, string s) { int i,j,cur; long long res=0; if(n) { vector<bool> visited(n,false); for(i=n-1;i>=1;i--) { if(s[0]==s[i]) { res+=i; for(j=i+1,cur=1;(j<n)&&(cur<i)&&(s[cur]==s[j]);j++,cur++) { if((!visited[j])&&(s[0]!=s[j])) { visited[j]=true; res+=i; } } } } } return res; } };