查找长度为n的子字符串,该字符串在给定字符串中重复最多次。
输入:abbbabbbb#2
输出:bb
我的解决方案:
public static String mrs(String s, int m) {
int n = s.length();
String[] suffixes = new String[n-m+1];
for (int i = 0; i < n-m+1; i++) {
suffixes[i] = s.substring(i, i+m);
}
Arrays.sort(suffixes);
String ans = "", tmp=suffixes[0].substring(0,m);
int cnt = 1, max=0;
for (int i = 0; i < n-m; i++) {
if (suffixes[i].equals(suffixes[i+1])){
cnt++;
}else{
if(cnt>max){
max = cnt;
ans =tmp;
}
cnt=0;
tmp = suffixes[i];
}
}
return ans;
}
可以比上述O(nm)时间和O(n)空间解决方案更好吗?
答案 0 :(得分:0)
对于长度为L
且给定长度为k
的字符串(不要混淆问题有时交换的n
和m
),我们可以计算k
中所有长度为O(L)
的子串的多项式哈希(请参阅Wikipedia以了解此子问题的一些详细说明)。
现在,如果我们将哈希值映射到它们出现的次数,我们会得到O(L)
中最常出现的值(具有高概率的HashMap,或者O(L log L)
中带有的值TreeMap中)。
之后,只需将获得最频繁哈希的子字符串作为答案。
此解决方案不会考虑哈希冲突。
我们的想法是只为应用程序减少足够的冲突概率(例如,如果它太高,则使用多个哈希值)。
如果应用程序要求我们绝对不会给出错误的答案,我们可以使用其他算法(例如KMP)检查O(L)
中的答案,并使用不同的哈希函数重新运行整个解决方案,只要答案结果证明是错误的。