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: 1 Explanation: Only the substring "a" of string "a" is in the string s.
Example 2:
Input: "cac" Output: 2 Explanation: There are two substrings "a", "c" of string "cac" in the string s.
Example 3:
Input: "zab" Output: 6 Explanation: 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;
}
};