力扣题解(环绕字符串中唯一的子字符串)

467. 环绕字符串中唯一的子字符串

定义字符串 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;
    }
    
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值