定义字符串 base
为一个 "abcdefghijklmnopqrstuvwxyz"
无限环绕的字符串,所以 base
看起来是这样的:
"...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd...."
.
给你一个字符串 s
,请你统计并返回 s
中有多少 不同非空子串 也在 base
中出现。
思路:本题中要求求所有存在的非空字串,且字串不能重复。首先先求所有存在的字串数目。
dp[i]表示以i结尾的所有字串的数目,则dp[i]=dp[i-1](若第i个元素可以和前面的元素组成字串)或者为0(不能组成字串)。此时dp中存放着所有非空字串的数目,但需要去重。去重主要利用了字串之间的特点,即若以同一个字符结尾,则二者必定一个是另一个的子串(因为以同一个字符结尾前面一定一样),则只需要存放其中更大的那个就行(因为dp[i]存放以i位置字符结尾的所有字串的数目,一定包含更少的那一部分)。
初始化时dp中每个元素是1,因为只有本身一个字符一定能构成子串。
dp[i]+=dp[i-1],用+=,可以想成dp[i-1]的所有可能加上了最后一个字符的数目(dp[i-1]),和只有最后一个字符的数目(dp[i])之和构成新的dp[i];
class Solution {
public:
int findSubstringInWraproundString(string s) {
set<string>sets;
int n=s.size();
vector<int>ret(n,1);
for(int i=1;i<n;i++)
{
if(s[i]-s[i-1]==1||s[i]=='a'&&s[i-1]=='z')
{
ret[i]+=ret[i-1];
}
}
vector<int>num(26,0);
for(int i=0;i<n;i++)
{
int low=s[i]-'a';
num[low]=max(num[low],ret[i]);
}
int sum=0;
for(auto e:num)
{
sum+=e;
}
return sum;
}
};