【回溯法】回溯法解决全排列问题

  • 题目:给定一个不含重复数字的数组 nums ,返回其所有可能的全排列 。你可以按任意顺序返回答案。
  • 示例 1:
    输入:nums = [1,2,3]
    输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
    题目链接:https://leetcode-cn.com/problems/permutations/
class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        res = []
        path = []
        n = len(nums)
        def backtracking(nums, n):
            if len(path) == n:
                res.append(path[:])
                return
            for i in range(n):
 				 # 因为没重复元素,所以只需判断当前元素是		
 				 # 否在path数组中即可,不用used数组
                if nums[i] not in path:
                    path.append(nums[i])
                    backtracking(nums, n)
                    path.pop()
                else:
                    continue
                
        backtracking(nums, n)
        return res
  • 题目2:给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
  • 示例 1:
    输入:nums = [1,1,2]
    输出:[[1,1,2],[1,2,1],[2,1,1]]
    题目链接:https://leetcode-cn.com/problems/permutations-ii/
class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        def backtracking(nums, used):
            if len(path) == len(nums):
                res.append(path[:])
                return 

            for i in range(len(nums)):
                if used[i]: 
                    continue
                if i >= 1 and  nums[i] == nums[i-1] and not used [i-1]:
                    continue
                used[i] = 1
                path.append(nums[i])
                backtracking(nums, used)
                path.pop()
                used[i] = 0
            
        res = []
        path = []
        nums.sort()
        # used 初始化都是零,含义:在nums数组中没有元素被使用
        # used = [1, 0, 1,] 含义:nums[0],nums[2]已经被使用 
        used = [0 for i in range(len(nums))]
        backtracking(nums, used)
        return res
  • 这次的全排列问题和之前的子集,组合问题一样,一道不用去重,一道去重。
    这次的全排列也是,因为是全排列所以每层的遍历都是遍历整个nums数组,如果nums中元素不重复,那我们只需要判断新的nums[i]是否已经在path中,但是对于有重复元素的nums,我们就需要一个新的used数组来判断该数字是否使用过。
    注意:经过这几道题一定要注意,在每层上去重时,一定要先对原来的nums数组进行排序,让相同的元素挨在一起。

关于python内置的全排列,组合库

  • product 笛卡尔积  (有放回抽样排列)
    就是nums中元素可以重复使用

  • permutations 排列  (不放回抽样排列)
    nums中元素不可重复使用

  • combinations 组合,没有重复  (不放回抽样组合)
    nums中元素不可重复使用

  • combinations_with_replacement 组合,有重复  (有放回抽样组合)
    nums中元素可以重复使用

专业的解释还是要看官方啦:https://docs.python.org/3.10/library/itertools.html

"""
每个函数都有两参数,
第一个是可迭代对象,
第二个是要从可迭代对象中抽取出来进行 排列 或 组合 的元素个数
"""

import itertools
# lis 无重复元素
lis = ['a', 'b', 'c']
# 有放回排序(元素可以重复使用)
for i in itertools.product(lis, repeat=2):
    print(i, end=' ')
"""
有放回排序(元素可以重复使用):
('a', 'a') ('a', 'b') ('a', 'c') ('b', 'a') ('b', 'b') ('b', 'c') ('c', 'a') 
('c', 'b') ('c', 'c') 
"""

# 无放回排序(元素不可以重复使用)
for i in itertools.permutations(lis, 2):
    print(i, end=' ')
"""
无放回排序(元素不可以重复使用):
('a', 'b') ('a', 'c') ('b', 'a') ('b', 'c') ('c', 'a') ('c', 'b') 
"""


# 无放回组合(元素不可以重复使用)
for i in itertools.combinations(lis, 2):
    print(i, end=' ')
"""
无放回组合(元素不可以重复使用):
('a', 'b') ('a', 'c') ('b', 'c') 
"""

# 有放回组合(元素可以重复使用)
for i in itertools.combinations_with_replacement(lis, 2):
    print(i, end=' ')
"""
有放回组合(元素可以重复使用):
('a', 'a') ('a', 'b') ('a', 'c') ('b', 'b') ('b', 'c') ('c', 'c') 
"""


# lis2 中有重复元素
lis2 = ['a', 'a', 'c']
# 有放回排序(元素可以重复使用)
for i in itertools.product(lis2, repeat=2):
    print(i, end=' ')
"""
有放回排序(元素可以重复使用): (这个a比较多为了解释,输出顺序进行了调整)
('a', 'a')(第一个a是下标为0的a,第二个a是下标为0的a) 
('a', 'a')(第一个a是下标为0的a,第二个a是下标为1的a) 
('a', 'a')(第一个a是下标为1的a,第二个a是下标为0的a) 
('a', 'a')(第一个a是下标为1的a,第二个a是下标为1的a) 
('a', 'c') ('a', 'c') (情况与上面类似)
('c', 'a') ('c', 'a') 
('c', 'c') 
"""
# 无放回排序(元素不可以重复使用)
for i in itertools.permutations(lis2, 2):
    print(i, end=' ')
"""
无放回排序(元素不可以重复使用):
('a', 'a') ('a', 'c') ('a', 'a') ('a', 'c') ('c', 'a') ('c', 'a') 
"""
# 无放回组合(元素不可以重复使用)
for i in itertools.combinations(lis2, 2):
    print(i, end=' ')
"""
无放回组合(元素不可以重复使用):
('a', 'a') ('a', 'c') ('a', 'c') 
"""
# 有放回组合(元素可以重复使用)
for i in itertools.combinations_with_replacement(lis2, 2):
    print(i, end=' ')
"""
有放回组合(元素可以重复使用):
('a', 'a') ('a', 'a') ('a', 'c') ('a', 'a') ('a', 'c') ('c', 'c') 
"""

你可能感兴趣的:(leetcode刷题总结,leetcode,算法,python)