最少的数字字符,可以使一组字符串唯一

时间:2013-04-25 07:07:48

标签: string algorithm data-structures prefix

可以使一组字符串唯一的最小数字字符(从第1个字符开始)是什么。

例如, 字符串集:

{
    'january',
    'february',
    'march',
    'april',
    'may',
    'june',
    'july'
}

现在,我们不能只使用第一个字符,因为'j'既是'june'也是'july'(同样,'m'在'march'和'may')。 我们也不能使用前2个字符,因为'ma'都在'march'和'may'中。

但是,我们可以使用前3个字符!

什么是最佳算法来返回这个数字(除了一个明显的蛮力)?

2 个答案:

答案 0 :(得分:2)

您可以优化的第一件事是对所需前缀的大小进行二进制搜索。函数是单调的 - 如果给定数量的字符n足够,那么任何大于n的值也会这样做。

第二 - 您可以为每个字符串计算滚动哈希值,以便您可以在恒定时间内获取每个字符串的给定前缀的哈希码。因此,您必须验证数字(哈希码)的唯一性,而不是字符串当然更快。我建议像rabin-karp一样滚动哈希。

答案 1 :(得分:2)

您可以对数据进行排序,并比较相邻条目之间不同的第一个字符的索引。这具有O(N log N)的复杂性或排序的复杂性。

如果可以将索引计算合并到比较函数中,则可以将结果视为副作用:结果应该是比较函数遇到的最大索引。

正如Steve Jessop评论的那样,问题可能无法解决。人们确实可以首先计算条目的最小长度。如果可以自由地实现比较函数,则另一个选项是,如果比较函数曾遇到字符串结尾,则返回-1。

int global_max = 0;
int compare(const char *a, const char *b) {
    int c=0;
    int result;  // result of comparison -- set as zero if an error has occured
    if (global_max < 0) return 0;
    do {
       if (*a==0 || *b==0) { global_max = -1; return 0; }
       c++;
    } while ((result = (*a++ - *b++)) == 0);
    if (c>global_max) global_max = c;
    return result;
}