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

Java 检查链表中子列表的方法的时间复杂度,java,linked-list,time-complexity,Java,Linked List,Time Complexity,我需要编写一个方法public int subList(CharList list) 获取一个列表并返回该列表存在的次数 例如: 我的列表是a b c d a b g e 参数列表它ab它将返回2 我的名单是b 参数列表为b b它将返回3 该方法应尽可能有效。 目前我的问题是,我不知道当他们说尽可能有效时,他们的意思是什么,如果我在列表中循环n次,每次我在两个列表中找到相同的字符,我循环并返回到我所在的位置,它将是O(n^2)?有没有更好的方法使is O(n)或以下?这是在字符串中有效搜索字符串

我需要编写一个方法
public int subList(CharList list)
获取一个列表并返回该列表存在的次数

例如:

我的列表是
a b c d a b g e

参数列表它
ab
它将返回2

我的名单是
b

参数列表为
b b
它将返回3

该方法应尽可能有效。


目前我的问题是,我不知道当他们说尽可能有效时,他们的意思是什么,如果我在列表中循环n次,每次我在两个列表中找到相同的字符,我循环并返回到我所在的位置,它将是O(n^2)?有没有更好的方法使is O(n)或以下?

这是在字符串中有效搜索字符串,即O(n)复杂度


当您找到第一个事件时,您可以继续在剩余列表中查找下一个事件,因此找到所有事件仍然是O(n)

为什么
O(n^2)
?这是
O(n)
,因为您只需要在
列表中迭代一次,让我们使用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;
}
public int countsublist(char[]列表,char[]子列表)
整数计数=0;
对于(i=0;i
这具有最坏情况的复杂性
O(N*M)
,其中
N
列表的长度
M
子列表的长度
。以及
O(N)
的最佳情况复杂性。。。当
列表
中没有
子列表
的第一个字符的实例时

还有其他各种算法可以提供更好的性能。。。具体到(我认为)
O(N/M)
最佳情况。一般的想法是,当存在不匹配时,可以使用列表[i+j]中字符的值来跳过某些字符

你可以在维基百科的网页上找到各种高级搜索算法的详细信息。。。其中还包括各算法复杂性的摘要


但需要注意的是,高级搜索算法都涉及一些预计算步骤,其复杂性是
M
的一些函数。如果
N
足够小,则预计算的成本可能超过搜索时节省的成本。(另一方面,如果您重复计算不同列表中的相同子列表,并且您可以重用预计算表,那么您可以摊销预计算成本…

低于
O(n)
,这听起来像是一个挑战;一种在列表上循环的
O(1)
方法。。。在最好的情况下,复杂性总是
O(n)
。@Boris蜘蛛:爬行爬行,爬行爬行,爬行爬行爬行。毛骨悚然,毛骨悚然。爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行爬行?因为如果没有,您可以重复调用
Collections.indexofpublist()
,在我的示例b(搜索bb)中也是如此。即使当我发现第二次发生时,我一直在看同一个索引,它仍然是O(n)?读了这篇文章后,我必须说这是一篇非常好的阅读,现在我的挑战是编码它;在bbbb中找到bb之后,你就去掉了字符include,在匹配索引之前,它把bbb留在了这里,然后你就用它来搜索了。当然,你可以摆脱更多的依赖于你的匹配模式,bbbb中的bb在这里是一个非常极端的例子,但它实际上是线性开销加起来使它变得复杂,理论上仍然是O(n)不太复杂。它是O(NM),其中N是列表长度,M是子列表长度。