无重复数字的全排列
题目描述
给定一个没有重复数字
的序列,返回其所有可能的全排列
。
示例
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
分析
利用 回溯法排列树模板 ,没有限定条件即就是没有冲突
。
代码
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
self.x = nums
self.n = len(nums)
self.backtrack(0)
return self.X
def __init__(self):
self.n = 0
self.x = []
self.X = []
def conflict(self, k):
return False
def backtrack(self, k):
if k>=self.n:
self.X.append(self.x[:])
else:
for i in range(k,self.n):
self.x[i], self.x[k] = self.x[k], self.x[i]
if not self.conflict(k):
self.backtrack(k+1)
self.x[i], self.x[k] = self.x[k], self.x[i]
有重复数字的全排列
题目描述
给定一个可包含重复数字
的序列,返回所有不重复的全排列
。
示例
输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
分析
解题思路与无重复数字的全排列一致
,只是结果进行去重
。
代码
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
self.x = nums
self.n = len(nums)
self.backtrack(0)
return list(set(tuple(i) for i in self.X))
def __init__(self):
self.x = []
self.n = 0
self.X = []
def conflict(self, k):
return False
def backtrack(self, k):
if k >= self.n:
self.X.append(self.x[:])
else:
for i in range(k, self.n):
self.x[i], self.x[k] = self.x[k], self.x[i]
if not self.conflict(k):
self.backtrack(k+1)
self.x[i], self.x[k] = self.x[k], self.x[i]
元素奇偶相间的排列
题目描述
给定一个没有重复数字
的序列,返回元素奇偶相间的排列
。
分析
与全排列
解题思路一致,只是每个节点进行冲突检测以剪枝
。
代码
class PermTree:
def __init__(self, data):
self.n = len(data)
self.x = data # 一个解
self.X = [] # # 一组解
#突检测:元素奇偶相间的排列
def conflict(self, k):
if k==0: # 第一个元素,肯定无冲突
return False
if self.x[k-1] % 2 == self.x[k] % 2: # 只比较 x[k] 与 x[k-1] 奇偶是否相同
return True
return False # 无冲突
def backtrack(self, k): # 到达第k个位置
if k >= self.n: # 超出最尾的位置
self.X.append(self.x[:]) # 注意x[:]
else:
for i in range(k, self.n): # 遍历后面第 k~n-1 的位置
self.x[k], self.x[i] = self.x[i], self.x[k]
if not self.conflict(k): # 剪枝
self.backtrack(k+1)
self.x[i], self.x[k] = self.x[k], self.x[i] # 回溯
def SovlePerm(self):
self.backtrack(0)
return self.X