简体   繁体   English

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

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

Given a binary string. 给出二进制字符串。 How to find occurances of "010" within a certain range of the string. 如何在字符串的某个范围内找到“010”的出现。
For example, I have the string "0100110" . 例如,我有字符串“0100110” If the given range is 3 7 ( 1 based indexing ) then the output will be 4 . 如果给定范围是3 7 (基于1的索引),则输出将为4 I could not find any faster way to solve it. 我找不到任何更快的方法来解决它。

While trying this I can solve it in O(N) complexity. 在尝试这个时,我可以用O(N)复杂度来解决它。 The approach is - firstly I point out the position of all '1' within the certain range and using those position I will figure out the number of '0' in both back and forth. 方法是 - 首先我指出所有'1'在一定范围内的位置,并使用这些位置,我将计算出来回的数字'0' And then multiply number of '0' found in back for a single '1' with number of '0' in found in forth. 然后将在后面找到的'0'的数字乘以单个'1' ,在第四个中找到'0'的数字。 Then sum up the multiplied result for each of the '1' within the certain range. 然后总结某个范围内每个'1'的相乘结果。

For the given example the position of '1' within the range is {5, 6} . 对于给定的示例,范围内的'1'的位置是{5,6} Now for index 5 I have number of '0' in both back and forth is 2 and 1 respectively. 现在对于索引5,我来回的数字都是'0'分别是21 So we can make subsequence "010" is 2 . 所以我们可以使子序列“010”2 Similarly for index 6 we also get the answer is 2 . 同样对于索引6我们也得到答案是2 In total we can make the subsequence "010" is 4 times in total. 总的来说,我们可以使子序列“010”总共为4次。

But when we have a number of Q queries of certain ranges for a given string then my approach easily reaches into the time complexity O(N 2 ) . 但是当我们对给定字符串有一些特定范围的Q查询时,我的方法很容易达到时间复杂度O(N 2 I tried a lot but failed to find a way to optimize it. 我尝试了很多,但未能找到优化它的方法。 Can anybody help me with an approach that is less than O(N 2 ) complexity? 任何人都可以帮助我采用低于O(N 2复杂度的方法吗? Just to mention the time limit should be 1 Second . 只是提到时间限制应该是1秒 It will be a plus if you provide a pseudo code. 如果您提供伪代码,这将是一个加号。

~Thanks in Advance. 〜先谢谢。

Pretreatment: make auxiliary array containing cumulative number of zeros upto given position (with aux[0]=0) 预处理:使辅助数组包含给定位置的累加零数(使用aux [0] = 0)

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

For given L..R range scan for ones, for every k index of 1 get number of zeros in range - O(1) operation 对于给定的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)

So we have O(RL) time per query and the worst case O(Q*N) for Q queries 因此,每个查询的时间为O(RL) O(Q*N) ,Q查询的最坏情况为O(Q*N)

But look at formula thoroughly: 但彻底看看公式:

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 

Note that LRSum and LRProd are constants for given query, and we have to calculate sums of A[k] for positions of ones and sum of squares for the same positions. 注意, LRSumLRProd是给定查询的常数,并且我们必须计算A的位置的A [k]和相同位置的平方和的和。 Seems we can use the same idea of cumulative array and get result in O(1) per query. 似乎我们可以使用相同的累积数组的想法,并获得每个查询O(1)结果。

Quick check gives (3+3)*5 - (9+9) - 4*2 = 30-18-8 = 4 for your example. 快速检查给出(3+3)*5 - (9+9) - 4*2 = 30-18-8 = 4为您的示例。

Using cumulative arrays: 使用累积数组:

  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