检查链表中子列表的方法的时间复杂度

时间:2014-03-22 23:40:04

标签: java linked-list time-complexity

我需要编写方法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)或以下?

3 个答案:

答案 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)最坏情况复杂度,其中Nlist的长度,M是{{1}的长度}}。 sublist的最佳案例复杂性... O(N)sublist的第一个字符没有实例时。

有各种其他算法可以提供更好的性能......直到(我认为)list最佳情况。一般的想法是,如果存在不匹配的情况,您可以使用list [i + j]中字符的值来跳过某些字符。

您可以在String Searching algorithms上的维基百科页面中找到各种高级搜索算法的详细信息...其中还包括相应算法复杂性的摘要。

但需要注意的是,高级搜索算法都涉及一些预先计算步骤,其复杂性是O(N/M)的一些功能。如果M足够小,预计算的成本可能会超过搜索时的保存成本。 (另一方面,如果您反复计算不同列表中的相同子列表,并且可以重复使用预先计算的表,那么您可以分摊预计算成本...)