(1)回溯算法团灭子集、组合、排列问题 -- 元素无重不可复选

回溯算法团灭子集、组合、排列问题

根据元素是否重复和是否可复选,分为以下三种变体:

1、元素无重不可复选
2、元素有重不可复选
3、元素无重可复选

该篇给出第一种情况的代码,另外两种的实现见上方变体链接。

python 复制代码
class NoRepeatAndSingle:
    """
    元素无重不可复选
    """
    def subsets(self, nums: List[int]) -> List[List[int]]:
        """
        子集问题
        :param nums:
        :return:
        """
        self.res = []
        self.track = []
        self.s_backtrack(nums, 0)
        return self.res

    def s_backtrack(self, nums, start):
        #  前序位置,每个节点的值都是⼀个⼦集
        self.res.append(self.track[:])

        for i in range(start, len(nums)):
            # 做选择
            self.track.append(nums[i])

            # 通过 start 参数控制树枝的遍历,避免产⽣重复的⼦集
            self.s_backtrack(nums, i+1)

            # 撤销选择
            self.track.pop()

    def combination(self, nums: List[int], k: int) -> List[List[int]]:
        """
        组合问题
        :param nums:
        :param k:
        :return:
        """
        self.res = []
        self.track = []
        self.c_backtrack(nums, 0, k)
        return self.res

    def c_backtrack(self, nums, start, k):
        #  base case
        if len(self.track) == k:
            self.res.append(self.track[:])
            return

        for i in range(start, len(nums)):
            # 做选择
            self.track.append(nums[i])

            # 通过 start 参数控制树枝的遍历,避免产⽣重复的⼦集
            self.c_backtrack(nums, i+1, k)

            # 撤销选择
            self.track.pop()

    def permute(self, nums: List[int]) -> List[List[int]]:
        """
        排列问题
        :param nums:
        :return:
        """
        self.res = []
        self.track = []
        self.used = [False] * len(nums)
        self.p_backtrack(nums)
        return self.res

    def p_backtrack(self, nums):
        #  base case
        if len(self.track) == len(nums):
            self.res.append(self.track[:])
            return

        for i in range(0, len(nums)):
            # 已经存在 track 中的元素,不能重复选择
            if self.used[i]:
                continue

            # 做选择
            self.used[i] = True
            self.track.append(nums[i])

            # 通过 start 参数控制树枝的遍历,避免产⽣重复的⼦集
            self.p_backtrack(nums)

            # 撤销选择
            self.used[i] = False
            self.track.pop()
相关推荐
老鼠只爱大米19 天前
LeetCode经典算法面试题 #39:组合总和(回溯法、动态规划、记忆化搜索等五种实现方案详细解析)
算法·leetcode·动态规划·剪枝·回溯算法·组合总和
老鼠只爱大米20 天前
LeetCode经典算法面试题 #22:括号生成(回溯法、动态规划、闭合数法等五种实现方案解析)
算法·leetcode·动态规划·递归·回溯算法·卡特兰数·括号生成
I_LPL23 天前
day23 代码随想录算法训练营 回溯专题2
算法·hot100·回溯算法·求职面试
I_LPL24 天前
day22 代码随想录算法训练营 回溯专题1
算法·回溯算法·求职面试·组合问题
卷卷的小趴菜学编程1 个月前
算法篇----递归回溯
c++·算法·递归·回溯算法·暴力搜索·floodfill算法·二叉树深搜
漫随流水1 个月前
leetcode回溯算法(46.全排列)
数据结构·算法·leetcode·回溯算法
漫随流水1 个月前
leetcode回溯算法(93.复原IP地址)
数据结构·算法·leetcode·回溯算法
漫随流水1 个月前
leetcode回溯算法(90.子集Ⅱ)
数据结构·算法·leetcode·回溯算法
漫随流水1 个月前
leetcode回溯算法(491.非递减子序列)
数据结构·算法·leetcode·回溯算法
漫随流水1 个月前
leetcode回溯算法(78.子集)
数据结构·算法·leetcode·回溯算法