【问题标题】:How to avoid generating all subsequences [duplicate]如何避免生成所有子序列[重复]
【发布时间】:2012-06-28 09:37:01
【问题描述】:

可能重复:
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 大于例如 30,这将不再可行。

如果n是200,真的可以系统地检查所有的解决方案吗?我该如何处理?

【问题讨论】:

  • 请您链接问题!

标签: algorithm dynamic-programming


【解决方案1】:

首先,对于每个字母 a..z,您会在 S 中获得它们的索引列表:

`p[x] = {i : S[i] = x}`, where `x = 'a',..,'z'`.

然后我们开始DP:

S: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
            ^          ^    ^
            r1        l2    r2

f(r1,l2,r2) 为任意长度L方形子序列(方形字符串的子序列)的数量,这样

  1. SS[L-1] = r1
  2. SS[L] = l2
  3. SS[2L-1] = r2

即前半部分正好在r1 结束,后半部分正好从l2 开始,到r2 结束。

那么算法是:

如果S[r1] = S[l2],则为f[r1,l2,l2] = 1,否则为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

【讨论】:

  • 谢谢。同时我还找到了this answer,所以我会检查它的复杂性。我现在没有足够的代表 (&gt;=15) 来投票。
  • @Dilbert,是的,很好,我认为答案具有完全相同的想法,但它省略了“如何有效地找到给定段中的相等字母对”部分:我使用p[x]为此,您甚至可以在p[x] 中使用二进制搜索。第二个:该解决方案对数组多了一个维度:第一个序列的开始,这对我来说似乎没有必要:它再次将n 上的时间和空间复杂度乘以一次,这使得这变得悲观(我不这样做)不信,太粗糙了)n^6.
  • @Dilbert,好的,n^4 现在。
  • +1 但是 200^4 并不是那么小恕我直言。 C# 的时间限制是 5 秒,在我的 1.6Ghz Core2duo 上执行 200^4 次单次乘法大约需要 8 秒,所以即使它通过了他们的测试,也将是非常接近的剃须刀。我相信应该存在一个时间复杂度较低的解决方案。
  • @Dilbert,是的,有一个n^3 解决方案,也许我稍后会编辑。您应该在问题中说明时间限制。
【解决方案2】:

有许多算法(例如Z-algorithm)可以在线性时间内生成前缀长度数组。也就是说,对于每个位置 i,它都会告诉您从位置 i 开始可以读取的最长前缀是什么(当然,对于 i = 0,最长的前缀是 n)。

现在请注意,如果您有一个从开头开始的方形字符串,那么在这个前缀长度数组中有一个位置 k,使得最长长度 >=k。所以你可以再次计算线性时间的数量。

然后删除字符串的第一个字母并做同样的事情。 总复杂度为 O(n^2)。

【讨论】:

  • 但请注意,问题是要求子序列,而不是子字符串。例如,baba 包含 3 个正方形子序列(baba,bb,aa)。
  • 又是一次面试,肯定没有人指望别人在面试中实现Z。
  • interviewstreet.com 不是采访,哈哈
  • :-) 是的,你是对的。
猜你喜欢
  • 2021-09-17
  • 1970-01-01
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 2016-09-20
  • 2017-12-26
  • 1970-01-01
相关资源
最近更新 更多