检查连续子序列总数的快速方法
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
你会选择 1000
、000100
、01
和 1
。对于每个字符串,计算包含 1
的子字符串的数量(关于每边 0
长度的简单方程)。将这些数量加起来。从整个输入的总数中减去。给你答案。
我有一个数字 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
你会选择 1000
、000100
、01
和 1
。对于每个字符串,计算包含 1
的子字符串的数量(关于每边 0
长度的简单方程)。将这些数量加起来。从整个输入的总数中减去。给你答案。