我需要编写方法public int subList (CharList list)
获取列表并返回此列表存在的次数。
例如:
我的列表是a b c d a b g e
参数列表a b
它将返回 2 。
我的列表是b b b b
参数列表为b b
,它将返回 3 。
该方法应尽可能高效。
目前我的问题是我不知道当他们说尽可能高效时他们是什么意思,如果我在列表中循环n次,每次我找到相同的字符我在两个列表上循环并返回到哪里我是O(n ^ 2)?是否有更好的方法是O(n)或以下?
答案 0 :(得分:2)
这是在字符串中有效搜索字符串,即O(n)复杂度
http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
当你发现第一次出现时,你可以继续寻找剩余列表中的下一个出现位置,这样它仍然可以找到所有出现的O(n)
答案 1 :(得分:1)
为什么O(n^2)
?它是O(n)
,因为您只需要遍历list
。
答案 2 :(得分:1)
让我们用char []来简化解释。
简单方法如下:
public int countSublists (char[] list, char[] sublist)
int count = 0;
for (i = 0; i < list.length; i++) {
for (j = 0; j <= sublist.length; j++) {
if (j = sublist.length) {
count++;
} else if (i + j > list.length || list[i + j] != sublist[j]) {
break;
}
}
}
return count;
}
O(N*M)
的最坏情况复杂度,其中N
是list
的长度,M
是{{1}的长度}}。 sublist
的最佳案例复杂性... O(N)
中sublist
的第一个字符没有实例时。
有各种其他算法可以提供更好的性能......直到(我认为)list
最佳情况。一般的想法是,如果存在不匹配的情况,您可以使用list [i + j]中字符的值来跳过某些字符。
您可以在String Searching algorithms上的维基百科页面中找到各种高级搜索算法的详细信息...其中还包括相应算法复杂性的摘要。
但需要注意的是,高级搜索算法都涉及一些预先计算步骤,其复杂性是O(N/M)
的一些功能。如果M
足够小,预计算的成本可能会超过搜索时的保存成本。 (另一方面,如果您反复计算不同列表中的相同子列表,并且可以重复使用预先计算的表,那么您可以分摊预计算成本...)