可能重复:
Square Subsequence
我一直在尝试解决interviewstreet.com上的“Square Subsequences”问题:
如果可以通过连接相同字符串的两个副本来获取字符串,则将其称为方形字符串。例如,“abab”,“aa”是方形字符串,而“aaa”,“abba”则不是。
给定一个字符串,该字符串的子序列有多少是方形字符串?
我尝试制定DP解决方案,但这种约束似乎无法规避:S will have at most 200 lowercase characters (a-z)
。
据我所知,查找长度为n
的列表的所有子序列为 O(2^n)
,一旦n
大于n
,就会停止可行比方说,30。
如果{{1}}为200,是否真的可以系统地检查所有解决方案?我该如何处理?
答案 0 :(得分:3)
首先,对于每个字母a..z
,您都会在S
中获得其索引列表:
`p[x] = {i : S[i] = x}`, where `x = 'a',..,'z'`.
然后我们开始DP:
S: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
^ ^ ^
r1 l2 r2
让f(r1,l2,r2)
为任意长度L
的平方子序列(方形字符串的子序列)的数量,以便
SS[L-1] = r1
SS[L] = l2
SS[2L-1] = r2
即。前半部分正好在r1
结束,后半部分恰好在l2
开始,到r2
结束。
然后算法:
如果f[r1,l2,l2] = 1
,则S[r1] = S[l2]
,否则为0。
for (l2 in 1..2L-1 )
for( r1 in 0..l2-1 )
for (r2 in l2..2L-1)
if( f(r1, l2, r2) != 0 )
for (x in 'a'..'z')
for (i,j: r1 < i < l2, r2 < j, S[i] = S[j] = x) // these i,j are found using p[x] quickly
f[i, l2, j] += f[r1, l2, r2]
最后,答案是f[.,.,.]
数组中所有值的总和。
基本上,我们将S
unisg l2
分为两部分,然后计算公共子序列。
我现在很难提供准确的时间复杂度估算,n^4
以下n^4
和n = 200
可以接受{{1}}。
答案 1 :(得分:0)
有许多算法(例如Z-algorithm)可以在线性时间内生成前缀长度数组。这是针对每个位置我告诉你从位置i开始可以读取的最长前缀是什么(当然i = 0,longetst前缀是n)。
现在注意,如果你从头开始有一个方形字符串,那么在这个前缀长度数组中有一个位置k,使得最长的长度是> = k。因此,您可以再次计算线性时间的数量。
然后删除你字符串的第一个字母并做同样的事情。 其总复杂度为O(n ^ 2)。