467. Unique Substrings in Wraparound String

来源:互联网 发布:cmd运行java步骤 编辑:程序博客网 时间:2024/06/03 18:58

Consider the string s to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz", so s will look like this: "...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd....".

Now we have another string p. Your job is to find out how many unique non-empty substrings of p are present in s. In particular, your input is the string p and you need to output the number of different non-empty substrings of p in the string s.

Note: p consists of only lowercase English letters and the size of p might be over 10000.

Example 1:

Input: "a"Output: 1Explanation: Only the substring "a" of string "a" is in the string s.

Example 2:

Input: "cac"Output: 2Explanation: There are two substrings "a", "c" of string "cac" in the string s.

Example 3:

Input: "zab"Output: 6Explanation: There are six substrings "z", "a", "b", "za", "ab", "zab" of string "zab" in the string s.

我的思路:

使用动态规划,并设置哈希数组,去重

class Solution {public:    int findSubstringInWraproundString(string p) {    // 建立动态数组dp[i][j]表示i-j范围的数是否是里面的数        //如果dp[i][j-1]==true&&(p[j]=p[j-1]+1||p[j]=='a'&&p[j-1]=='z')        //从左到右遍历        //有重复的值,怎么办?使用哈希数组呗,但是这里建立的是子串的首字母和子串长度        int n=p.size();        vector<vector<int>> dp(n,vector<int>(n,0));        set<pair<char,int>> store;        int res=0;        for(int i=0;i<n;i++)            for(int j=i;j<n;j++)            {                if(i==j)                 {                    dp[i][j]=1;                }                else                {                    if(dp[i][j-1]==true&&(p[j]==p[j-1]+1||(p[j]=='a'&&p[j-1]=='z')))                    {                        dp[i][j]=1;                    }                }                if(dp[i][j]==1&&store.find({p[i],j-i})==store.end())                {                     store.insert(make_pair(p[i],j-i));                    res++;                }            }        return res;    }};

只能过一部分

O(n)的解法:

考虑以某子母结尾的最大连续子串,子串的长度就是以这个子母结尾的连续子串的个数,考虑去重,只需要考虑每个子母结尾的最长连续子串的长度就可以了。遍历一遍字符串,更新当前的子母结尾的连续子串长度,最后遍历一遍子母序列求和。

class Solution {public:    int findSubstringInWraproundString(string p) {        vector<int> dp(26,0);        int c=0;        for(int i=0;i<p.size();i++)        {            if(i>0&&(p[i-1]==p[i]-1||p[i-1]-p[i]==25))                c++;            else                c=1;            dp[p[i]-'a']=max(dp[p[i]-'a'],c);        }        int res=0;        for(int i=0;i<26;i++)            res+=dp[i];        return res;    }};


原创粉丝点击