public void check_10() {
for (string i : list) {
Integer a = hashtable.get(i);
if (a > 10) {
hashtable.remove(i);
}
}
}
Would this be O(1) or O(n)? I'm guessing O(n), but isn't it reusing the spot of memory a each time making it O(1)?
Space complexity asks "how much additional space (asymptotically, speaking) am I using in this snippet of code". Here's how a space complexity analysis would work, showing two general cases (for your code snippet):
hashtable
and 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);
}
}
}
Assuming you have N
elements in hashtable
and no elements are removed (i.e., a <= 10
for all N
elements), at the termination of the loop, you will have N
elements remaining in hashtable
. Furthermore, each String
in the N
keys in the hashtable
contains up to S
characters. Lastly, each Integer
in the N
values in the hashtable
is constant.
Similarly, you have a possible M
number of strings in list
, where each String
may contain up to S
characters.
Lastly, the Integer a
does not contribute to the analysis because it references memory already accounted for. We can consider this Integer a
constant memory still.
Therefore, assuming hashtable
and list
had been declared in the method, you are looking at a space complexity of O(N*S + M*S + I)
.
That said, asymptotically, we don't really care about I
(the Integer a
) because it is constant size that is likely much smaller than N
and M
. Similarly, S
is likely much smaller than both N
and M
. This means the space complexity is O(N + M)
. Because both are linear terms, we can (carefully) reduce this to O(n)
, where n
is a linear term that is a linear combination of N and M
.
hashtable
and list
or elsewhere declared (as in your example)// 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);
}
}
}
In this method, list
and hashtable
have already been allocated elsewhere, which means that the space complexity for this method is O(1)
because we are only using constant space in Integer a
and String i
(even though technically, they are references to previously allocated memory -- you can consider the constant space as a result of storing the reference).
but isn't it reusing the spot of memory a each time making it O(1)?
It depends on what you mean by "reusing" the spot in memory. In theory, space complexity analysis does not exactly consider the implementation details of the language in this sense. This means that if you had a loop like
for (int i = 0; i < N; i++) {
T myvar = new T();
}
you don't consider the implications of what's happening to myvar
after each loop iteration. By "implications of what's happening" I mean, does the garbage collector reclaim memory after each iteration or are you continually allocating N spots of memory on the heap? In the GC case, it would be O(1)
since you are reusing memory. In the "infinite" allocation case, it would be O(N)
since you now have N
spots allocated. Again, in theory, this is usually not considered in the analysis, and any T myvar = new T()
is usually considered to be O(1) regardless of whether it sits in a loop or not.
In general, though, if you are referring to reusing the same spot in memory for list
and hashtable
each iteration, the answer is simpler. Consider the following:
public void foo() {
int list[] = {1, 2, 3, 4};
for (int i = 0; i < list.length; i++) {
System.out.println(list[i]);
}
}
Even though list
is declared once and we're only iterating through list
and printing the contents, foo()
is still O(n) in memory complexity because we have allocated list
, where in the asymptotic case could have up to n
elements. Therefore, regardless of whether it reuses the same or different spots in memory, they both still contribute to a linear space complexity.
In your specific case, though, both list
and hashtable
had already been allocated elsewhere in the program and are not introduced here, so they do not contribute to the complexity, and Integer a
and String i
are only constant in memory. Therefore, this method will be O(1)
.
Other than 2 constant sized variables string i
and Integer a
this method does not allocate any extra space. Which means this loop clearly has constant space complexity .ie. O(1).
To clarify it further, I would rather ask you a question :
Do you call (iterative)binary search an O(n) space complexity algorithm ?
Absolutely not.
Your function check_10() uses a preallocated list and hash table (just like iterative binary search uses preallocated sorted array) and 2 constant space variables so it has O(1) space complexity.
PS : I am clarifying the doubt raised by OP in comments of this answer from here onwards ->
As pointed out by MichaelRecachinas, String
and Integer
in this loop are references. They are not a copy so they won't contribute anything to the space complexity of this function.
PPS: Integer a
and String i
are allocated memory only once and then are reused in each iteration of the loop.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With