[leetcode]排列&组合&子集(python)

文章目录

  • 排列
    • 全排列不重复,T46
    • 排列有重复不可复选,T47
    • 排列无重复可复选
  • 组合
    • 组合不重复不可复选,T77
    • 组合总和有重复不可复选,T40
    • 组合总和无重复可复选,T39
  • 子集
    • 子集不重复不可复选,T78
    • 子集有重复不可复选,T90

排列

全排列不重复,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)

你可能感兴趣的:(leetcode刷题笔记,leetcode,python,算法,数据结构)