This is a typical backtracking solution with O(n) space. It is short, clean and easy to follow.

```
class Solution:
# @param num, a list of integer
# @return a list of lists of integers
def permuteUnique(self, num):
numPool = {}
for i in num:
if i in numPool:
numPool[i] += 1
else:
numPool[i] = 1
return self.dfs(numPool, [[]])
def dfs(self, numDic, filled):
returned_list = []
for eachkey in numDic:
if numDic[eachkey] > 0:
pass_list = [x + [eachkey] for x in filled]
numDic[eachkey] -= 1
extended_lists = self.dfs(numDic,pass_list)
numDic[eachkey] += 1
returned_list.extend(extended_lists)
return returned_list if len(returned_list) > 0 else filled
```