Problem Statement in English
You’re given an integer array nums that may contain duplicates. Your task is to return all possible subsets (the power set) of the array, ensuring that no duplicate subsets are included in the result.
Approach
In order to avoid duplicates, we need to be able to going ahead when we just skipped a number and encounter the same number again.
This is where sorting the array comes in handy. By sorting the array, we can easily skip over duplicates during our backtracking process.
The rest of the approach is similar to the 78. Subsets, where we model the solution as a decision tree. We will explore two options at each index: include the current number in the subset or exclude it.
And we’re done!
Solution in Python
class Solution:
def subsetsWithDup(self, nums: list[int]) -> list[list[int]]:
res = []
curr = []
N = len(nums)
nums.sort()
def dfs(i):
if i >= N:
res.append(curr.copy())
return
curr.append(nums[i])
dfs(i + 1)
curr.pop()
i += 1
while i < N and nums[i] == nums[i - 1]:
i += 1
dfs(i)
dfs(0)
return res
Complexity
Time: $O(2^n)$
Since we generate $2^n$ possibilities per choice, and since we have $n$ choices, that’s $n*2^n$.Space: $O(n)$
Since we are using a recursive function, the maximum depth of the recursion tree will ben, which is the length of the input array. Therefore, the space complexity is $O(n)$ due to the recursion stack.
And we are done.