I am trying to understand difference/similarity in complexities when writing the code to generate powerset in 2 ways:
def powerset(s, i, cur):
if i==len(s):
print(cur)
return
powerset(s, i+1, cur+s[i]) # string addition is also possibly O(n^2) here?
powerset(s, i+1, cur)
powerset("abc", 0, "")
Output:
['abc', 'ab', 'ac', 'a', 'bc', 'b', 'c', '']
This is going into recursion, with 2 choices at each step (adding s[i]
or not), creating 2 branches. Leading to 2^n
and adding to the array/printing is another O(n)
, leading to O(n*2^n)
Also thinking about it in the terms of branches^depth
= O(2^n)
The space complexity for this will be: O(n)
? Considering max depth of the tree to go up to n
by the above logic.
And with this:
s = "abc"
res = [""]
for i in s:
res += [j+i for j in res]
I get the same output.
But here, I see 2 for loops and the additional complexity for creating the strings -- which is possibly O(n^2)
in Python. Leading to possible O(N^4)
as opposed to O(n*2^n)
in the solution above.
Space complexity here seems to me to be O(n)
since we are reserving space for just the output. But no additional space, so overall: O(1)
Is my understanding for these solutions in time and space correct? I was under the impression that computing powerset is O(2^n)
. But I figured maybe its a more optimized solution? (even though the second solution seems more naive).
https://stackoverflow.com/questions/34008010/is-the-time-complexity-of-iterative-string-append-actually-on2-or-on
Here, they suggest using arrays to avoid the `O(n^2)` complexity of string concatenation.