Learnitweb

Space Complexity

What Is Space Complexity?

As discussed earlier, algorithm complexity includes two main components:

  1. Time Complexity – the amount of time needed to complete the algorithm.
  2. Space Complexity – the amount of memory required to complete the algorithm.

In this section, we’ll focus on the space complexity, which is usually denoted as the function S(n).

All the rules for evaluating space complexity using Big-O notation are identical to those used for time complexity.

Example 1: Simple Function Call

Let’s consider a simple function:

doubleNum(int x) {
    return x * 2;
}

foo(int n) {
    for (int i = 1; i <= n; i++) {
        doubleNum(i);
    }
}

When calling \texttt{foo(4)}, here’s what happens:

  • The function \texttt{doubleNum} is called inside a loop.
  • Each call to \texttt{doubleNum} creates a stack frame in memory (RAM), which includes local variables and system data.
  • As soon as the function completes, its stack frame is removed from memory.

So, at any given moment, only one stack frame is present in memory.

Thus, space complexity is:

S(n) = O(1)

Example 2: Recursive Function

Now, let’s analyze the space complexity of a recursive function:

foo(int n) {
    if (n == 1) return;
    foo(n - 1);
}

Let’s execute \texttt{foo(4)}.

  • Calling \texttt{foo(4)} creates a stack frame.
  • Then \texttt{foo(3)} is called → another stack frame is added.
  • Then \texttt{foo(2)}, and finally \texttt{foo(1)}.

So, at one point, we have 4 stack frames in memory.

Therefore, space complexity is:

S(n) = O(n)

This happens because recursive calls accumulate on the call stack before returning.

Example 3: Recursive Function with Multiple Calls

Let’s now analyze a recursive function that makes two recursive calls:

foo(int n) {
    if (n == 1) return;
    foo(n - 1);
    foo(n - 1);
}

You might think the entire recursive tree of calls remains in memory—but that’s not true.

Here’s what actually happens:

  • The recursive tree is traversed depth-first.
  • At most, the memory holds a path from root to leaf, which is the height of the tree.

So, for n = 4, the maximum number of active stack frames is 4 (i.e., the height of the tree).

Thus, even though the function makes 2^n calls over time, the space complexity remains:

S(n) = O(n)

Type of FunctionSpace Complexity
Non-recursive functionO(1)
Single-recursive callO(n)
Multiple-recursive callsO(n) (due to call stack depth)

Strings and Space Complexity

Now, let’s evaluate how string operations impact space complexity.

String Concatenation

In most languages (e.g., Java, JavaScript), strings are immutable. That means every time you concatenate a string, a new string is created.

So, if you concatenate a string of length n with one character, the memory required is:

S(n) = n + 1 = O(n)

Example: Loop Concatenation

String s = "";
for (int i = 1; i <= n; i++) {
    s = s + "a";
}

Let’s break it down:

IterationNew StringSpace Used
1“a”1
2“aa”2
3“aaa”3
n“aaaa…a”n

Total space used across all iterations:

S(n) = 1 + 2 + 3 + \dots + n = \frac{n(n + 1)}{2} = O(n^2)

Final Summary

Let’s consolidate everything:

  • Non-recursive function:

S(n) = O(1)

Recursive function (single call):

S(n) = O(n)

Recursive function (multiple calls):

S(n) = O(n)

String concatenation once:

S(n) = O(n)

String concatenation inside a loop:

S(n) = O(n^2)