空间复杂度询问“我在这段代码的 sn-p 中使用了多少额外空间(渐近地说)”。以下是空间复杂度分析的工作原理,显示了两种一般情况(对于您的代码 sn-p):
示例 1:按值传递 hashtable 和 list
// assume `list` and `hashtable` are passed by value
public void check_10(List<String> list, HashMap<String, Integer> hashtable) {
for (String i : list) {
Integer a = hashtable.get(i);
if (a > 10) {
hashtable.remove(i);
}
}
}
假设您在hashtable 中有N 元素并且没有删除任何元素(即,对于所有N 元素,a <= 10),在循环结束时,您将在@ 中保留N 元素987654329@。此外,hashtable 中的 N 键中的每个 String 最多包含 S 字符。最后,hashtable 中的 N 值中的每个 Integer 都是常量。
同样,list 中可能有多个 M 字符串,其中每个 String 最多可包含 S 个字符。
最后,Integer a 对分析没有帮助,因为它引用了已经占用的内存。我们仍然可以考虑这个Integer a 常量内存。
因此,假设在方法中声明了hashtable 和list,那么您将看到O(N*S + M*S + I) 的空间复杂度。
也就是说,渐近地说,我们并不真正关心I(Integer a),因为它的大小可能比N 和M 小得多。同样,S 可能比N 和M 都小得多。这意味着空间复杂度为O(N + M)。因为两者都是线性项,我们可以(小心地)将其简化为O(n),其中n 是一个线性项,它是N and M 的线性组合。
示例 2:通过引用传递 hashtable 和 list 或在其他地方声明(如您的示例)
// assume `list` and `hashtable` are passed by reference or
// declared elsewhere in the class as in
//
// public void check_10() {
public void check_10(List<String> list, HashMap<String, Integer> hashtable) {
for (String i : list) {
Integer a = hashtable.get(i);
if (a > 10) {
hashtable.remove(i);
}
}
}
在这个方法中,list和hashtable已经分配到别处了,也就是说这个方法的空间复杂度是O(1),因为我们只在Integer a和String i中使用了常量空间(甚至尽管从技术上讲,它们是对先前分配的内存的引用——您可以将常量空间视为存储引用的结果。
但它不是每次都重用内存点 a 使其 O(1) 吗?
这取决于您所说的“重用”内存中的位置是什么意思。理论上,空间复杂度分析并没有完全考虑这个意义上的语言的实现细节。这意味着如果你有一个像
这样的循环
for (int i = 0; i < N; i++) {
T myvar = new T();
}
您没有考虑每次循环迭代后myvar 发生的事情的影响。通过“正在发生的事情的含义”我的意思是,垃圾收集器是在每次迭代后回收内存,还是你不断地在堆上分配 N 个内存点?在 GC 情况下,它将是 O(1),因为您正在重用内存。在“无限”分配情况下,它将是O(N),因为您现在分配了N 点。同样,理论上,这通常不会在分析中考虑,任何T myvar = new T() 通常被认为是 O(1),无论它是否位于循环中。
不过,一般来说,如果您指的是在每次迭代中为list 和hashtable 重复使用内存中的同一位置,那么答案会更简单。考虑以下几点:
public void foo() {
int list[] = {1, 2, 3, 4};
for (int i = 0; i < list.length; i++) {
System.out.println(list[i]);
}
}
即使list 被声明了一次并且我们只是迭代list 并打印内容,foo() 的内存复杂度仍然是 O(n),因为我们已经分配了 list,其中在渐近case 最多可以有n 个元素。因此,无论它是否重用内存中相同或不同的点,它们都仍然会导致线性空间复杂度。
tl;博士
但是,在您的具体情况下,list 和 hashtable 都已在程序的其他地方分配,因此此处未介绍,因此它们不会增加复杂性,Integer a 和 String i 是只存在于记忆中。因此,这个方法将是O(1)。