【问题标题】:total substrings with k onesk 个子串的总数
【发布时间】:2015-07-12 17:12:14
【问题描述】:

给定一个二进制字符串 s,我们需要找到它的子字符串的数量,其中正好包含 k 个字符为 '1'。

例如:s = "1010" and k = 1, answer = 6。

现在,我在累积和数组上使用二进制搜索技术解决了这个问题。

我还使用了另一种方法来解决它。方法如下:

  1. 对于每个位置 i,找到以 i 结尾的所有子字符串包含 正好 k 个字符为 '1'。

  2. 要找到以 i 结尾的全部子串,其中恰好包含 k 个为 1 的字符,它可以表示为索引集 j,使得子串 j 到 i 恰好包含 k 个“1”。答案将是集合的大小。现在,要找到给定位置 i 的所有这样的 j,我们可以将问题改写为找到所有这样的 j

从 [1] 到 [j - 1] 的个数 = 从 1 到 i 的总个数 - [从 j 到 i 的总个数 = k]。

即从 [1] 到 [j - 1] 的个数 = C[i] - k

等于 C[j - 1] = C[i] - k,

其中 C 是累积和数组,其中 C[i] = 字符串从 1 到 i 的字符总和。 现在,问题很简单,因为我们可以通过计算总和为 C[i] - k 的所有前缀,使用等式找到 j 的所有可能值。

但我找到了这个解决方案,

int main() {
    cin >> k >> S;
    C[0] = 1;
    for (int i = 0; S[i]; ++i) {
        s += S[i] == '1';
        ++C[s];
    }
    for (int i = k; i <= s; ++i) {
        if (k == 0) {
            a += (C[i] - 1) * C[i] / 2;
        } else {
            a += C[i] * C[i - k];
        }
    }
    cout << a << endl;
    return 0;
}

在代码中,S 是给定的字符串,K 如上所述,C 是累积和数组,a 是答案。 我不知道使用乘法的代码到底在做什么。 有人能解释一下这个算法吗?

【问题讨论】:

  • 我刚刚理解了k = 0部分,如果k = 0,由于c[i]是累积和等于i的出现次数,我们必须有(c[i] - 1)子串中相邻的零。因此,总和为零的可能子串的数量 = (c[i] - 1) * (c[i] - 1 + 1) / 2 = c[i] * (c[i] - 1) / 2,计算所有字符为零的字符串的可能子字符串的数量。
  • 我想我也得到了另一部分。

标签: string algorithm


【解决方案1】:

如果您看到C[i] 的计算方式,C[i] 表示ith 1i+1st 1 之间的字符数。

如果你举个例子S = 1001000

                   C[0] = 1 
                   C[1] = 3 // length of 100
                   C[2] = 4 // length of 1000

所以来回答你的疑问,为什么要乘法

说你的K=1,然后你想找出只有一个1的子字符串,现在你知道在第一个1之后有两个零since C[1] = 3。所以子串的数量将是 3,因为你必须包括这 1。

       {1,10,100}

但是当你来到第二部分时:C[2] =4

现在如果你看到1000 并且你知道你可以创建 4 个子字符串(等于 C[2])

     {1,10,100,1000}

您还应该注意到C[1]-1 在此1 之前有零。

因此,通过包含这些零,您可以创建更多子字符串,在这种情况下,通过包含 0 一次

      0{1,10,100,1000}
      => {01,010,0100,01000}

00 一次

      00{1,10,100,1000}
      => {001,0010,00100,001000}

所以基本上你正在制作以1 开头的C[i] 子字符串,你可以在这个之前添加i 的零个数并制作另一个C[i] * C[i-k]-1 子字符串。 i varies from 1 to C[i-k]-1(-1 因为我们想留下最后一个)。

   ((C[i-k]-1)* C[i]) +C[i]
   => C[i-k]*C[i] 

【讨论】:

    猜你喜欢
    • 2013-03-05
    • 2023-03-29
    • 1970-01-01
    • 2020-10-02
    • 2015-08-14
    • 1970-01-01
    • 2014-05-18
    • 2020-11-11
    • 2015-12-22
    相关资源
    最近更新 更多