回溯法-全排列

无重复数字的全排列

题目描述

给定一个没有重复数字的序列,返回其所有可能的全排列

示例

输入: [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
发布了219 篇原创文章 · 获赞 85 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/z_feng12489/article/details/102979204