检查连续子序列总数的快速方法

Fast way to check consecutive subsequences for total

我有一个数字 0、1 或 2 的列表(最多 10,000 个)。 我需要查看有多少个连续子序列的总数不为 1。我当前的方法是对每个列表执行:

cons = 0
for i in range(seqlen+1):
    for j in range(i+1, seqlen+1):
        if sum(twos[i:j]) != 1:
            cons += 1

因此,示例输入为:

[0, 1, 2, 0]

输出为

cons = 8

因为 8 个工作子序列是:

[0] [2] [0] [1,2] [2, 0] [0, 1, 2] [1, 2, 0] [0, 1, 2, 0]

问题在于,简单地遍历所有这些子序列(范围内的 i,范围内的 j)花费的时间几乎比允许的要多,而且当添加 if 语句时,代码花费的时间太长 运行 在服务器上。 (要明确的是,这只是一个更大问题的一小部分,我不只是要求解决整个问题)。无论如何,有没有其他方法可以更快地检查?我想不出任何不会导致每次都需要进行更多操作的事情。

使用滑动 window 技术来解决这类问题。取两个变量first和last跟踪window的范围。所以你从等于第一个元素的总和开始。如果总和大于所需值,则从总和中减去 'first' 元素并将总和递增 1。如果总和小于所需值,则添加 'last' 指针的下一个元素并将最后一个元素递增 1。时间总和等于某些计数器所需的增量。

对于NOT,计算总和为'1'的子序列的个数,然后从可能的子序列总数中减去,即n * (n + 1) / 2

我想我看到了问题:您的术语不正确/多余。根据定义,子序列是一系列连续的元素。

不要对每个候选人求和。相反,确定每个候选者的总和 1,然后从所有子序列(简单代数)的计算量中减去该总数。

所有的 1-sum 候选都是正则表达式形式 0*10*:一个 1 两侧或两侧被任意数量的 0 包围。

找出所有这样的最大长度字符串。例如,在

210002020001002011

你会选择 1000000100011。对于每个字符串,计算包含 1 的子字符串的数量(关于每边 0 长度的简单方程)。将这些数量加起来。从整个输入的总数中减去。给你答案。