找到长度为K的良好子串,使其重要性最低

时间:2018-12-13 07:44:26

标签: algorithm

  

将一个好的子字符串定义为一个以'x'开头,以'z'结束并且长度可以被3整除的子字符串。将字符串的重要性定义为与之相交的好子字符串的数目(如果不相交,则除外)它本身就是很好的)。考虑一个长度为N(1≤N≤10^ 5)的字符串,它由x,y,z组成。给定整数K(1≤K≤10^ 5),找到具有最小重要性且长度为K的良好子字符串。您需要打印最小重要性。

我有解决此问题的想法,但我无法真正对其进行编码。首先,它必须在线性/线性时间范围内完成。

我的想法是,将源自i的良好子字符串的数量存储在beg [i]中。如果我们从右端开始使用一个计数器,并根据“ z”的模3位置向右添加,就可以做到这一点。如果i%3 == j,则beg [i] = i右边位置j + 2 mod 3中“ z”的数量。同样,我们可以创建end [i]以获得以i结尾的好子字符串的数量。如果i位置包含'y'或如果它没有形成一个好的子字符串,我们将写beg [i]或end [i]等于0。

现在,对于下一部分(找到交集),我不确定如何产生线性/线性解。 对于特定间隔[arr [i],arr [i + K-1]],交点数将为

=在a [i]之前开始的子串数-在a [i]之前结束的子串数+在a [i]之后开始并在a [i + K-1之前,之后, ]。

这是主意。我敢肯定,有一些方法可以进行预计算,并且可以修改我写的上述公式,以便得出答案。

1 个答案:

答案 0 :(得分:1)

请注意,accumulated [i] =从索引i或更大的索引开始有多少个好的字符串。答案公式中可能有一个错误,但是这个主意应该是正确的。

for i = 0 to N
    beg[i] = end[i] = 0

for i = 0 to 3
    z[i] = 0
    x[i] = 0

for i = 0 to N
    if str[i] == 'z'
        z[i % 3]++

for i = 0 to N
   if str[i] == 'z'
       z[i % 3]--
       end[i] = x[i % 3]
   if str[i] == 'x'
       beg[i] = z[i % 3]
       x[i % 3]++
       total += beg[i]

for i = 0 to N
    accumulated[i] = total
    total -= beg[i]

answer = N + 1

beforeStart = beforeEnd = 0
for i = 0 to N - k
    if str[i] == 'x' and str[i + k] == 'z'
        answer = min(answer, beforeStart - beforeEnd + (accumulated[i + k] - accumulated[i]) + beg[i] - 1)

    beforeStart += beg[i]
    beforeEnd += end[i]

print(answer)