题目描述
给定一个没有重复数字的序列,返回其所有可能的全排列。
算法思路
数学上的全排列总数很容易计算,即是阶乘。考虑如何通过算法列举出所有的排列组合呢?
最简单的应该是for循环的嵌套,但是序列很长时就难以嵌套,所以采用递归。依然是一个for循环,进入循环后将当前变量pop出列表,然后进入递归,继续pop,直到列表为空。然后开始返回,每一层返回都将当层pop出的元素重新insert进序列。
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
n=len(nums)
def Sum(ls,n,A=[],K=[]):
for i in ls:
x = ls.index(i)
y=ls.pop(x)
A.append(y)
Sum(ls,n,A,K)
if len(A)==n:K.append(A[:])
ls.insert(x,y)
A.pop()
return K
return Sum(nums,n)
这是一个粗糙的递归算法。虽然最好成绩
执行用时 :40 ms, 在所有 Python3 提交中击败了86.42%的用户
内存消耗 :13.4 MB, 在所有 Python3 提交中击败了53.38%的用户
————————————————————————————
这里抄一个大佬的解答(代码更加简洁):
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
res = []
def backtrack(nums, tmp):
if not nums:
res.append(tmp)
return
for i in range(len(nums)):
backtrack(nums[:i] + nums[i+1:], tmp + [nums[i]])
backtrack(nums, [])
return res
递归部分如下:
def backtrack(nums, tmp):
if not nums:
res.append(tmp)
return
for i in range(len(nums)):
backtrack(nums[:i] + nums[i+1:], tmp + [nums[i]])
和我的思路是一致的,但是更加巧妙,只是多个切片操作得到的时间复杂度并不低。
————————
2020/04/25 晴。打卡 全排列。
现在回过头来做回溯算法好简单。
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
def helper(ls,t=[]):
if not ls:
res.append(t)
for i in range(len(ls)):
helper(ls[:i]+ls[i+1:],t+[ls[i]])
res=[]
helper(nums)
return res