在HackerEarth测试中我被问到了这个问题,我什至无法形成算法。
问题是-
Count the number of substrings of a string, such that any of their permutations is a palindrome.
因此,对于aab
,答案是5
-a
,a
,b
,aa
和aab
(可以排列成aba
的形式。)
我觉得这是动态编程,但是我找不到子问题可能具有什么样的关系。
编辑: 所以我认为递归关系可能是
dp[i] = dp[i-1] + 1 if str[i] has already appeared before and
substring ending at i-1 has at most 2 characters with odd frequency
else dp[i] = dp[i-1]
不知道这是否正确。
答案 0 :(得分:0)
如果我没有误解你的问题,我倾向于认为这是一个数学问题。假设字符串的长度为n
,则答案应为n *(n + 1)/ 2,即无穷级数之和。参见https://en.wikipedia.org/wiki/1_%2B_2_%2B_3_%2B_4_%2B_%E2%8B%AF
例如,字符串abcde
,我们可以获取子字符串
a
,b
,c
,d
,e
,
ab
,bc
,cd
,de
,
abc
,bcd
,cde
,
abcd
,bcde
,
abcde
。
您可能会从我列出子字符串的方式中找到答案。
答案 1 :(得分:0)
我可以想到O(n^2)
-遍历长度大于1的子字符串,从索引(0,1)到(0,n-1),然后从(1,n-1)向下到(1 ,3),然后从(2,3)到(2,n-2),然后从(3,n-2)向下到(3,5)...等。
遍历时,维护每个字符的当前频率图,以及具有奇数计数的字符数和具有偶数计数的字符数的总和。如果我们使用的子串的长度为(1)个奇数长度且只有一个字符具有奇数频率,或者是(2)个偶数长度且无字符具有奇数频率,则在每次迭代时更新这些值并添加回文排列子串的总数。 >
(为单字符回文计数添加字符串长度。)
答案 2 :(得分:0)
所以这是我的解决方案,可以为您提供帮助。
通过运行嵌套循环,可以获得输入的每个可能子串的列表,对于每个子串,您都必须检查子串是否可以形成回文。
现在如何检查字符串/子字符串是否可以形成回文:
如果子字符串的出现次数的奇数字母大于1,则它们不能形成回文。代码如下:
布尔字符串CanbeFormAPalindrome(字符串s) { int奇数值,字母[26];
for(int i =0; i< s.length(); i++)
{
alphabet[s[i]-'a']++;
}
for(int i=0; i<26; i++)
{
if(alphabet[i]%2==1)
{
oddValues++;
if(oddValues>1) return FALSE;
}
}
return TRUE;
}
希望有帮助。
答案 3 :(得分:0)
您可以在 O(N) 时间和 O(N) 空间复杂度内轻松完成
请注意,如果子串的排列是否为回文,唯一的问题是其中奇数字符的奇偶校验,因此只需创建每个字符的奇偶校验掩码,现在对于任何有效子串,最多可以有 1 位不同对我们当前的掩码,让我们迭代哪个位不同,并添加相应的答案。
这是一个 C++ 代码(假设 unordered_map 是每个查询的 O(1))
string s;
cin>>s;
int n=s.length();
int ans=0;
unordered_map<int,int>um;
um[0]=1;
int mask=0;
for(int i=0;i<n;++i){
mask^=1<<(s[i]-'a');
ans+=um[mask];
for(int j=27;j>=0;--j){
ans+=um[mask^(1<<j)];
}
um[mask]++;
}
cout<<ans;
注意整数溢出。