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

把字符串 s 看作是“abcdefghijklmnopqrstuvwxyz”的无限环绕字符串,所以 s 看起来是这样的:"...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd....". 

现在我们有了另一个字符串 p 。你需要的是找出 s 中有多少个唯一的 p 的非空子串,尤其是当你的输入是字符串 p ,你需要输出字符串 s 中 p 的不同的非空子串的数目。 

注意: p 仅由小写的英文字母组成,p 的大小可能超过 10000。

示例 1:

输入: "a"
输出: 1
解释: 字符串 S 中只有一个"a"子字符。

示例 2:

输入: "cac"
输出: 2
解释: 字符串 S 中的字符串“cac”只有两个子串“a”、“c”。.

示例 3:

输入: "zab"
输出: 6
解释: 在字符串 S 中有六个子串“z”、“a”、“b”、“za”、“ab”、“zab”。.

思路:由于封装字符串是26个字符按顺序无限循环组成的,那么满足题意的p的子字符串要么是单一的字符,要么是按字母顺序的子字符串,包括后一个字符比前一个字符大1(abc),或者后一个字符比前一个字符小25(zab)。

zabdeacde为例:划分成zab、de、a、cde四段,会发现a包括在za(zab)里,de包括在cde里。所以对于每一个字符来讲,我们只需要找到以该字符为结尾的最长的字符串,就可以涵盖其它的所有情况。以该字符为结尾的最长的字符串,构成的总子串个数为,以该字符为结尾的最长的字符串的长度。如b,找到zab,一共能构成三个b, ab, zab.

class Solution {
public:
    int findSubstringInWraproundString(string p) {
        vector<int>cnt(26);
        int re=0, len=1;
        for(int i=0; i<p.size(); ++i){
            if(i>0 && (p[i]==p[i-1]+1 || p[i]==p[i-1]-25)) 
                len++;
            else{
                len=1;
            }
            cnt[p[i]-'a']=max(cnt[p[i]-'a'], len);
        }
        for(auto x:cnt) re+=x;
        return re;
    }
};
发布了312 篇原创文章 · 获赞 32 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/Scarlett_Guan/article/details/99186341
今日推荐