给定一个由S
小写英文字母组成的字符串N
。
假设我们有一个列表L
,包含字符串S
的所有非空子串。
我需要计算从列表K
中精确选择L
个相等字符串的方式的数量(请注意,子字符串的长度不必等于k
)。
1≤N≤5000
1≤K≤10^ 9
Exampple:
Let S=ababa.
As List L = {"a", "b", "a", "b", "a", "ab", "ba", "ab", "ba", "aba", "bab", "aba", "abab", "baba", "ababa"}
let k=2
方式的数量为7:
("a", "a")
("a", "a")
("a", "a")
("b", "b")
("ab", "ab")
("ba", "ba")
("aba", "aba")
类似地:
let k=3
没有办法是1:
("a", "a", "a")
答案 0 :(得分:1)
“所有子串的列表”。你为什么要列出所有子串?假设你有一百万个字符的字符串,有5000亿个子字符串。所有子串的列表根本不需要解决问题。
如果K = 0则有一种方法。 如果K = 1则有N种方式。
对于k = 1到N,长度为k的每个子串可以从0到N-k的索引开始,即N-k + 1个子串。识别不同的字符串并使用哈希表计算每个字符串的数量。然后对于出现n次的每个不同的字符串,n> = k,将(n over K)加到计数中。
就是这样。
你可以通过首先查看长度为1的字符串来更快地完成它,忽略所有少于K个相等字符串的字符串,计算方法的数量,然后为每个字符串添加另一个字符并重复。假设K = 5,字符串中有一百万个字符,并且只有两个长度为6的子字符串发生了五次或更多次,那么您只需要在这两个子字符串中添加字符。
答案 1 :(得分:0)
为给定字符串构建suffix array。
走遍这个数组,寻找(至少k个)邻居siffix的常见起始符号。
答案 2 :(得分:0)
以下是JavaScript中的内容:
function choose(n,k){
if(k>n)return 0;if(k==0||n==k)return 1;var p=n;for(var i=2;i<=k;i++)p*=(n+1-i)/i;return p;
}
function f(str,k){
var n = str.length,
h = {},
count = 0;
for (var i=0; i<n; i++){
var s = "";
for (var j=i; k <= n - j + i && j < n; j++){
s += str.charAt(j);
if (h[s])
h[s]++;
else
h[s] = 1;
}
}
for (var i in h)
count += choose(h[i],k);
return count;
}
输出:
console.log(f("ababa",2));
console.log(f("ababa",3));
7
1
答案 3 :(得分:0)
正如其他人注意到的那样,你并不真正需要子串列表。因为您只关心相等的子串,所以您只需要计算子串出现的次数,并且可以使用哈希/字典/映射来跟踪它。然后,当子字符串出现k
次时,精确选择n
个相等子串的方法的数量是二项式系数c(n,k)
。您可以为每个不同的子字符串添加所有这些二项式系数,并得到答案。
请注意,如果您要为多个k
值提出此问题,则只需构建一次哈希/字典/映射。
答案 4 :(得分:-2)
如果没有关于您正在学习的语言的任何细节,我相信您可以通过一个简单的嵌套循环来实现这一目标。只需将每个值与数组或列表中的所有值进行比较。