如何比较Java中两种方法的复杂性?
如何比较这两种方法的如何比较Java中两种方法的复杂性?,java,time-complexity,space-complexity,Java,Time Complexity,Space Complexity,如何比较这两种方法的O复杂性 以下是第一种方法: protected static List<Integer> removeDuplicates1(List<Integer> source) { List<Integer> tmp = new ArrayList<Integer>(); for (Integer element : source) { if (!tmp.contains(element)) {
O
复杂性
以下是第一种方法:
protected static List<Integer> removeDuplicates1(List<Integer> source) {
List<Integer> tmp = new ArrayList<Integer>();
for (Integer element : source) {
if (!tmp.contains(element)) {
tmp.add(element);
}
}
//Collections.sort(tmp);
return tmp;
}
protectedstatic List removeDuplicates1(列表源){
List tmp=new ArrayList();
for(整型元素:源){
如果(!tmp.包含(元素)){
tmp.add(要素);
}
}
//Collections.sort(tmp);
返回tmp;
}
第二个:
protected static List<Integer> removeDuplicates2(List<Integer> source) {
return new ArrayList<Integer>(new HashSet<Integer>(source));
}
protectedstatic List removeDuplicates2(列表源){
返回新的ArrayList(新的HashSet(source));
}
UPD
我不知道如何计算这两种方法的O复杂度
UPD2
好的,第一种方法的时间复杂度是
O(n^2)
,第二种是O(n)
。内存使用情况如何?谁更贪婪?为什么?第二个更好O(n)
复杂性(O(n^2)
第一个)
对于第一个循环(n
)中的列表,对于每个操作,运行contains()
,然后遍历tmp列表以查找元素是否存在(还有一个n
)
对于第二种方法,在
集合中添加的操作是常量,因此实际上只有一种n
第二种方法工作得更好,因为它的复杂性是O(n)
,而第一种方法在O(n^2)
中运行
在使用大O表示法的情况下,第二个解决方案的复杂性是O(n),因为它只在列表中循环一次。而在第一种情况下,它首先for循环运行一次,但internal contains method在临时列表上再次运行。因此,这种情况下的复杂性是O(n^2)。不要尝试在Java中这样做,只需尝试在伪代码中这样做
在第一个问题中,有两个整数列表;两个数字列表。如果没有给出任何其他规则,我们可以假设两个列表的长度都约为n项
您正在遍历其中一个列表,并为其中的每个数字做一些事情。如果有n个数字,那就是n个步骤。对于这n个步骤中的每一步,您都会问“其他列表是否有此编号?”
要查看列表中是否有数字,最糟糕的情况是它没有,这意味着您必须检查列表中的每个项目才能找到。如果第二个列表可以和第一个列表一样大,那么这也是n个步骤
把这些放在一起:
浏览n个项目的列表,并对每个项目执行n项操作
让我知道你的想法,然后我会编辑这个答案
对于第二个代码段,请将其拆分
首先要做的是使用输入中的所有项创建一个哈希集。将一个项目插入哈希集需要多长时间?如果插入n个项目,则将单个插入的时间乘以n
发生的第二件事是调用新的ArrayList。检查API以确保其正在执行的操作:
它使用HashSet集合中的所有项创建ArrayList。插入到数组列表需要多长时间?将其乘以项数(n)得到答案
由于这些步骤是分开的,所以它们是分开的。无论哪一个具有更高的big-O复杂度,都是主要的,您可以忽略另一个。如果它们都有相同的big-O复杂性,那就是答案;你可以忽略一个,因为O(2n)与O(n)的复杂度相同;常量(如2x)会被删除。如果无法提供大量列表并测量时间(至少是时间复杂度),请查看源代码。t有一些工具可以监视堆/堆栈的使用情况,其中最简单的工具之一是位于bin目录中的内置jdk“jconsole”,您知道如何计算每一个的O复杂度吗?如果你这样做了,那么比较它们应该很容易。如果你没有,那么请编辑你的问题,以反映这一点,因为措辞似乎建议你这样做。“我不确定问题到底是什么。@帕森特我一直认为算法复杂性是一个与理论有关而与实践无关的问题。@yshavit我不知道怎么做。哪一个?二者都你读过什么计算大O的资源,在这里应用这些资源你不了解什么?到目前为止,这个问题非常广泛,基本上是“我如何计算大O”-对于so的格式来说太广泛了。所有这些都是通过查看ArrayList和HashSet的实现(或者相信Javadoc所说的话)学到的。可以向ArrayList添加一些内容,使其包含O(1)。@laune no.contains()用于列表检查所有元素。事实上,它会遍历列表。当然可以添加一些东西。。。但这不是ArrayList,当然我知道java.util.ArrayList.contains的作用。请阅读我写的内容:我说过这是可能的,您需要查看实现以确保。OP似乎怀疑检查实施的必要性。向ArrayList中添加某些内容不会使其失去契约,即其实现的接口。@laune,例如,如果您修改list使其具有常量time contains(),则意味着您应该以某种方式合并list并设置它,从而使我们找到方法2。嘿,这就是我想说的:-)您需要查看实际的实现。我想这是Palcente的建议。如果你要否决投票,请告诉我为什么,以便我可以改进它?你在编辑过程中删除了一些错误的内容,因此我收回-1。