文章目录
排列
全排列不重复,T46
def permute(nums):
def backtrack(path):
if len(path) == n:
res.append(path[:])
for num in nums:
if not num in path:
path.append(num)
backtrack(path)
path.pop()
n = len(nums)
res = []
path = []
backtrack(path)
return res
- 时间复杂度:O(n * n!)
- 空间复杂度:O(n)
排列有重复不可复选,T47
def permuteWithDup(nums):
def backtrack(path):
if len(path) == n:
res.append(path[:])
return
for i in range(n):
if used[i]:
continue
#注意这里添加的not used[i-1],只有前面的相邻相等元素用过了才用这个
if i > 0 and nums[i] == nums[i - 1] and not used[i-1]:
continue
path.append(nums[i])
used[i] = True
backtrack(path)
path.pop()
used[i] = False
n = len(nums)
if n == 0:
return [[]]
nums.sort()
path = []
res = []
used = [False] * n
backtrack(path)
return res
- 时间复杂度:O(n * n!)
- 空间复杂度:O(n)
排列无重复可复选
组合
组合不重复不可复选,T77
题目:1…n中大小为k的组合
def combine(n,k):
res = []
path = []
def backtrack(start, k):
if k == 0:
res.append(path[:])
for i in range(start, n + 1):
path.append(i)
backtrack(i + 1, k - 1)
path.pop()
backtrack(1, k)
return res
- 时间复杂度:O(k * C(n,k))
- 空间复杂度:O(n)
组合总和有重复不可复选,T40
def combinesum2(candidates, target):
def backtrack(start,cursum):
if cursum == target:
res.append(path[:])
return
if cursum > target:
return
for i in range(start, n):
if i > start and candidates[i] == candidates[i - 1]:
continue
path.append(candidates[i])
backtrack(i + 1, cursum + candidates[i])
path.pop()
candidates.sort()
n = len(candidates)
res = []
path = []
backtrack(0,0)
return res
- 时间复杂度:O(n * 2^n)
- 空间复杂度:O(n)
组合总和无重复可复选,T39
def combinationSum(candidates, target):
def backtrack(start, cursum):
if cursum == target:
res.append(path[:])
return
if cursum > target:
return
for i in range(start, len(candidates)):
path.append(candidates[i])
backtrack(i,cursum+candidates[i])
path.pop()
res = []
path = []
backtrack(0, 0)
return res
- 时间复杂度:O(S),S为所有可行解的长度之和
- 空间复杂度:O(target)+ O(n)
子集
子集不重复不可复选,T78
def subset(nums):
def backtrack(nums, start):
res.append(path[:])
for i in range(start+1, n):
path.append(nums[i])
backtrack(nums, i + 1)
path.pop()
n = len(nums)
path = []
res = []
backtrack(nums, 0)
return res
- 时间复杂度:O(n * 2^n)
- 空间复杂度:O(n)
子集有重复不可复选,T90
def subsetWithDup(nums):
def backtrack(start):
res.append(path[:])
for i in range(start, n):
if i > start and nums[i] == nums[i - 1]:
continue
path.append(nums[i])
backtrack(i + 1)
path.pop()
path = []
res = []
nums.sort()
n = len(nums)
backtrack(0)
return res
- 时间复杂度:O(n * 2 ^ n)
- 空间复杂度:O(n)