繁体   English   中英

如何在二进制字符串的特定范围内找到010的数量

[英]How to find number of 010 in a certain range of a binary string

给出二进制字符串。 如何在字符串的某个范围内找到“010”的出现。
例如,我有字符串“0100110” 如果给定范围是3 7 (基于1的索引),则输出将为4 我找不到任何更快的方法来解决它。

在尝试这个时,我可以用O(N)复杂度来解决它。 方法是 - 首先我指出所有'1'在一定范围内的位置,并使用这些位置,我将计算出来回的数字'0' 然后将在后面找到的'0'的数字乘以单个'1' ,在第四个中找到'0'的数字。 然后总结某个范围内每个'1'的相乘结果。

对于给定的示例,范围内的'1'的位置是{5,6} 现在对于索引5,我来回的数字都是'0'分别是21 所以我们可以使子序列“010”2 同样对于索引6我们也得到答案是2 总的来说,我们可以使子序列“010”总共为4次。

但是当我们对给定字符串有一些特定范围的Q查询时,我的方法很容易达到时间复杂度O(N 2 我尝试了很多,但未能找到优化它的方法。 任何人都可以帮助我采用低于O(N 2复杂度的方法吗? 只是提到时间限制应该是1秒 如果您提供伪代码,这将是一个加号。

〜先谢谢。

预处理:使辅助数组包含给定位置的累加零数(使用aux [0] = 0)

  0 1 0 0 1 1 0  //string
0 1 1 2 3 3 3 4  //aux array A[]

对于给定的L..R范围扫描1,对于每1 k索引1获得范围内的零 - O(1)操作

P[k] = (A[k] - A[L-1]) * (A[R] - A[k])
S = Sum(P[k], k=L..R)

因此,每个查询的时间为O(RL) O(Q*N) ,Q查询的最坏情况为O(Q*N)

但彻底看看公式:

P[k] = (A[k] - A[L-1]) * (A[R] - A[k]) = 
       A[k] * (A[R] + A[L-1]) - A[k]^2 - A[R] * A[L-1] = 
       A[k] * LRSum - A[k]^2 - LRProd
S = Sum(A[k] for ones) * LRSum - Sum(A[k]^2) - LRProd * NumOfOnes 

注意, LRSumLRProd是给定查询的常数,并且我们必须计算A的位置的A [k]和相同位置的平方和的和。 似乎我们可以使用相同的累积数组的想法,并获得每个查询O(1)结果。

快速检查给出(3+3)*5 - (9+9) - 4*2 = 30-18-8 = 4为您的示例。

使用累积数组:

  0 1 0 0 1  1  0  //string
0 1 1 2 3 3  3  4  //aux array A[]
0 0 1 1 1 4  7  7  //aux array B[]
0 0 1 1 1 10 19 19  //aux array C[]

Result = (B[R] - B[L-1]) * (A[R] + A[L-1]) - (C[R] - C[L-1]) - 
                 A[R] * A[L-1] * (R - L - 1 - (A[R] - A[L-1])) = 
         (7-1) * (4 + 1) - (19 - 1) - 4 * 1 * (7 - 2  - 4 + 1) = 4

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM