0
$\begingroup$

Say I have an array and I want to add those values to something else. What is the space complexity if I incrementally take one of those values off the first list and add it to the second? For example, I'm trying to convert a list to a string. I know that if I do the following, the space complexity will be O(N):

a = [1,2,3,4]
b = set(a)

But if instead I incrementally shrunk a, what would the space complexity be?

a = [1,2,3,4]
b = set()
for _ in range(len(a)):
    b.add(a.pop())

Now b has what I want and a is empty. Does that make it O(1) in space complexity?

If the language matters, I'm most interested in Python, but I would like to know the most general answer as well.

$\endgroup$
  • 4
    $\begingroup$ It all depends on what your model for space complexity is. Does the space used for the input count or not? What about the output? And, if neither counts, do you allow only sequential or also random access to either of those? These considerations make subtle differences not only for the space complexity of algorithms but also for theoretic models such as TMs (and related complexity-theoretic results). $\endgroup$ – dkaeae Feb 23 '19 at 17:39
  • 2
    $\begingroup$ This seems to be a python-specific question, since it is only possible to answer it if we know the details of python implementation. $\endgroup$ – Yuval Filmus Feb 23 '19 at 17:56
  • 1
    $\begingroup$ "Does that make in O(1) in space complexity?" So, do you mean the second algorithm will reuse the space freed by a.pop(), which is not obvious at all? $\endgroup$ – John L. Feb 23 '19 at 20:05
  • $\begingroup$ I'm voting to close this question as off-topic because it depends on the implementation details of python. $\endgroup$ – Yuval Filmus Feb 24 '19 at 15:01
1
$\begingroup$

Space complexity is all very well on something like a Turing machine: you just define the space complexity to be the number of different tape cells that the tape head visits. For real computers, things get much more complicated and very implementation-dependent.

It is possible that the algorithm you describe runs in constant space. If the array a is stored earlier in memory than the string b, the system could, in principle, delete the last character of a, shuffle everything after it back one memory cell, then add a character onto the end of b, so no extra memory is used.

In reality, though, it's much more likely that the system doesn't keep moving things around and just allocates new memory each time a character is added to b, which is probably linear space. Except it could be worse. Maybe, every time you try to make b bigger, the system actually allocates completely new storage for the extended string, which could give quadratic space usage. Or maybe it's not that dumb and, each time you extend the string beyond its current memory allocation, it allocates a new chunk of memory that's double the size, so it can do lots of appends without reallocating memory every time. That would be linear, again.

And in real reality, what actually happens probably depends very much on what else is running on the machine. If there's lots of free memory, the system might be very happy to allocate fresh memory each time you extend the string, and it might only free the memory used by the old versions right at the end. If there is little free memory, it might free up unused memory much more aggressively.

So your code probably uses at least a linear amount of memory, but it's not really possible to be more precise than that.

| cite | improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.