2. 全排列
2.1 不含重复数字的全排列
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 1:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例 2:
输入:nums = [0,1]
输出:[[0,1],[1,0]]
示例 3:
输入:nums = [1]
输出:[[1]]
提示:
1 <= nums.length <= 6
-10 <= nums[i] <= 10
nums 中的所有整数 互不相同
题解:
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
res = []
track = []
self.backtrack(res, track, nums)
return res
def backtrack(self, res, track, nums):
# bad case
if len(track) == len(nums):
res.append(track[:])
return
for i in range(0, len(nums)):
if nums[i] in track:
continue
track.append(nums[i])
self.backtrack(res, track, nums)
track.pop() # 撤销条件
另一种写法:
class Solution:
def permute(self , num: List[int]) -> List[List[int]]:
if len(num) == 1:
return [num]
res = []
used = [False] * len(num) # 记录当前节点是否已经选择
def backtrack(path):
if len(path) == len(num):
res.append(path[:])
return
for i in range(len(num)):
# 如果以及用过就跳过
if used[i]:
continue
used[i] = True
path.append(num[i]) # 做选择
backtrack(path) # 递归
path.pop() # 撤销选择
used[i] = False
backtrack([])
return res
2.2 有重复项数字的全排列
描述
给出一组可能包含重复项的数字,返回该组数字的所有排列。结果以字典序升序排列。
# 示例一
输入:
[1,1,2]
返回值:
[[1,1,2],[1,2,1],[2,1,1]]
# 示例二
输入:
[0,1]
返回值:
[[0,1],[1,0]]
class Solution:
def permuteUnique(self, num: List[int]) -> List[List[int]]:
res = []
used = [False] * len(num)
num.sort()
def backtrack(path):
if len(path) == len(num):
res.append(path[:])
return
for i, item in enumerate(num):
if used[i]:
continue
# 与不含重复数字的全排列不同之处
# 当前元素与前一个元素相同,且前一个元素已使用过
if i > 0 and item == num[i-1] and used[i-1] == True:
continue
used[i] = True
path.append(item) # 做决策
backtrack(path)
path.pop() # 撤销选择
used[i] = False
backtrack([])
return res