代码的空间复杂性是什么?
我认为它是O(1),因为我没有在技术上将所有输入存储到一个数组中,我把它分成2个数组。
这段代码应该带有重复的数组,并找到两个不重复的数字。
我的代码:
FORMAT
答案 0 :(得分:1)
空间复杂度是最好的情况" O(1)
和"最坏情况" O(N)
。最好的情况是nums
中的所有数字都相同,最坏的情况发生在各种情况下......包括接近N / 2重复时,这是您的预期用例。
在所有情况下,时间复杂度为O(N)
。
这是我的推理。
我们假设哈希函数表现良好,那么HashSet.add
和HashSet.contains
的时间复杂度都是O(1)
。
Integer.valueOf(int)
的时间复杂度也是O(1)
。
这些O(1)
操作最多执行"某些常数"两个O(N)
循环中的时间,使整个计算O(N)
及时。
这有点复杂,但我们只考虑所有int
值都是唯一的最坏情况。这句话
if (!temp.contains(i)) temp.add(i);
else temp2.add(i);
将Integer.valueOf(i)
添加到temp
或temp2
。在这种特殊情况下,它们都会以temp
结尾。 (考虑一下......)这意味着我们最终得到temp
集中的N 唯一条目,temp2
集合中没有。
现在HashSet
条目N
所需的空间为O(N)
。 (比例常数很大......但是我们在这里讨论空间复杂性这是不相关的。)
当所有int
值相同时,会出现最佳情况。然后,您最终会在temp
中输入一个条目,在temp2
中输入一个条目。 (相同的值会重复添加到temp2
集合中......但不执行任何操作。)两个地图的空间使用情况均为O(1)
。
但是(我听到你问)Integer.valueOf(int)
创建的对象怎么样?我认为他们不算数:
除非它们可以访问(通过HashSet
个对象之一),否则Integer
对象将被垃圾回收。因此,在通常被认为是 1 中的的意义上,它们不算作空间用途。
智能编译器实际上可以完全消除对Integer
个对象的需求。 (不是当前的HotSpot Java编译器,但将来我们可以在生产编译器中看到这样的东西。)
1 - 如果您开始考虑临时(即立即无法访问)Java对象作为空间利用率并总结此利用率,您将得到无意义的结果;例如具有O(N^2)
"空间利用率的应用程序"在O(N)
大小的堆中运行。临时对象执行计数,但仅限于可达时。在您的示例中,贡献为O(1)
。