def permute(nums: List[int]) -> List[List[int]]:
idx = set([i for i in range(len(nums))])
# recursion function
def helper(idx_used):
# remaining idx to place
idx_to_place = idx - idx_used
out = [] # list of all combinations for current + next indexes
# try all elements that remain to place for this index value
for j in idx_to_place:
tmp = helper(idx_used | {j}) # for next index call the function with the updated remaining elements
out.extend([[nums[j]] + l for l in tmp]) # add the combinations of current index j and next indexes
# return the list of combination (list of list) if out is empty return [[]] as a list of list is expected
return(out if out else [[]])
return(helper(set()))