LeetCode-全排列-回溯
题目回顾
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
题解
参考官方题解
时间复杂度是 O ( ∑ k = 1 N P ( N , k ) ) O(\sum_{k=1}^{N}P(N,k)) O(∑k=1NP(N,k)), P ( N , k ) = N ! ( N − k ) ! = N ( N − 1 ) . . . ( N − k + 1 ) P(N, k) = \frac{N!}{(N - k)!} = N (N - 1) ... (N - k + 1) P(N,k)=(N−k)!N!=N(N−1)...(N−k+1)
空间复杂度 O ( N ! ) O(N!) O(N!),
执行用时: 120 m s 120 ms 120ms
回溯递归思想
回溯法是一种通过探索所有可能的候选解来找出所有的解的算法。
首先如果不考虑如何写代码,数学思维考虑应该如何做,
1-2-3-4,1-2-4-3,1-3-2-4,1-3-4-2,1-4-3-2,1-4-2-3,
2-1-3-4,2-1-4-3,2-3-1-4,2-3-4-1,2-4-3-1,2-4-1-3,
...
以这样的方式进行有序寻找。
-
如果第一个整数有索引
n
,意味着当前排列已完成。将当前排序的顺序存入 -
遍历索引
first
到索引n - 1
的所有整数。- 在排列中放置第
i
个整数, 即swap(nums[first], nums[i])
. - 继续生成从第
i
个整数开始的所有排列:backtrack(first + 1)
. - 现在回溯,即通过
swap(nums[first], nums[i])
还原.
- 在排列中放置第
python代码实现
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
def backtrack(first=0):
if first==n: #如果相等
lists.append(nums[:])
else:
for i in range(first,n):
nums[first],nums[i]=nums[i],nums[first]
backtrack(first+1) #从第 i 个整数开始的所有排列
nums[first],nums[i]=nums[i],nums[first] #回溯
n=len(nums)
lists=[]
backtrack()
return lists