【问题标题】:Codility challenge - why does this solution work?Codility 挑战 - 为什么这个解决方案有效?
【发布时间】:2017-10-03 16:52:24
【问题描述】:

问题:

给定一串数字,计算作为任何回文的字谜的子词(一致子序列)的数量。

例子:

对于输入字符串“02002”,结果应为 11,即:

“0”、“2”、“0”、“0”、“2”、“00”、“020”、“200”、“002”、“2002”、“02002”

我可以看到下面的解决方案有效,但我不明白为什么。特别是我不明白内循环的意义。谁能解释一下这背后的逻辑?

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define M 1000000007
#define COLORS 10
#define SUBSETS (1 << (COLORS))

int solution(char *S) {
    int len, result;
    int *values;
    int v, idx, middle, mask;

    result = 0;
    values = calloc(SUBSETS, sizeof(int));
    //new_values = calloc(SUBSETS, sizeof(int));
    len = strlen(S);
    mask = 0;

    for (idx = 0; idx < len; idx++) {
        v = S[idx] - '0';
        mask ^= (1 << v);
        values[mask ^ (1 << v)] += 1;
        result = (result + values[mask]) % M;
        for (middle = 0;  middle < COLORS; middle++) {
            result = (result + values[mask ^ (1 << middle)]) % M;
        }
    }
    return result;
}

如果需要更多详细信息,请访问:https://codility.com/programmers/task/winter_lights/。

【问题讨论】:

  • 是时候学习如何调试了...顺便说一句,我能看到的唯一回文是 "2002"...
  • @LPs,我多次调试它,但仍然无法理解它为什么起作用。再读一遍问题,这是回文的字谜。

标签: c algorithm palindrome anagram


【解决方案1】:

对于每个idx,您要计算i,这样从i 到idx 的灯光可以形成一个回文。这意味着每种类型的灯都有偶数个,或者除了一个(位于回文中间)之外的所有灯都有偶数个。

代码使用一个技巧来计算i,以避免 O(n^2) 行为。在处理索引idx 处的光之后,数组values 包含每个m 的数量i&lt;idx,这样从0 到i 的光序列包含每个光的偶数或奇数(取决于m 的位)。例如,values[3] 包含初始灯光序列的数量(最多 idx,其中包含奇数个灯光 0 和 1,以及偶数个其他灯光)。

使用这个数组,计算以idx 结尾的改组回文数很容易:如果直到idx 的掩码是mask,那么所有灯数为偶数的回文数数与该数相同具有相同掩码的左序列(即:values[mask])。类似地,除了奇数一盏灯(middle)之外,具有偶数盏灯的回文数与带有掩码mask^(1&lt;&lt;middle)的左序列数相同。

【讨论】:

  • 你能澄清一下吗:例如,values[3] 包含灯的初始序列数(最多 idx,奇数个灯 0 和 1,偶数个其他灯)?
  • 3 = 0b00000011。位 0 和 1 已设置。
  • 这部分我还是没看懂,为什么会这样:如果到idx为止的mask是mask,那么所有灯数为偶数的回文数与灯数相同具有相同掩码的左序列(即:values[mask])
  • 因为如果灯光 [0..i] 有遮罩 m,灯光 [0..idx] 有遮罩 m,那么灯光 [i+1...idx] 有遮罩 0。而遮罩0 对应于每种颜色的光的计数是偶数。
  • 我会接受你的回答,即使我仍然不明白。也许我会在几个月内:)
猜你喜欢
  • 2013-12-28
  • 1970-01-01
  • 1970-01-01
  • 2020-01-16
  • 1970-01-01
  • 2022-01-16
  • 2014-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多