可以使一组字符串唯一的最小数字字符(从第1个字符开始)是什么。
例如, 字符串集:
{
'january',
'february',
'march',
'april',
'may',
'june',
'july'
}
现在,我们不能只使用第一个字符,因为'j'既是'june'也是'july'(同样,'m'在'march'和'may')。 我们也不能使用前2个字符,因为'ma'都在'march'和'may'中。
但是,我们可以使用前3个字符!
什么是最佳算法来返回这个数字(除了一个明显的蛮力)?
答案 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;
}