(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()
相关推荐
KaiPeng-Nie4 天前
代码随想录day23 | leetcode 39.组合总和 40.组合总和II
java·数据结构·算法·leetcode·回溯算法
KaiPeng-Nie5 天前
代码随想录day22 | 回溯算法理论基础 leetcode 77.组合 77.组合 加剪枝操作 216.组合总和III 17.电话号码的字母组合
java·算法·leetcode·剪枝·回溯算法·回归算法·递归函数
给自己做减法2 个月前
有趣的回溯法寻求最优解
算法·回溯算法
AI小杨2 个月前
【数据结构和算法】四、回溯算法的原理讲解和实战演练
数据结构·人工智能·算法·leetcode·机器学习·回溯算法
小小皮卡丘啃算法6 个月前
89.格雷编码
java·数据结构·算法·leetcode·格雷编码·回溯算法
丷从心·7 个月前
【回溯算法】【Python实现】符号三角形问题
python·回溯算法
我是镜流的狗8 个月前
飞机降落(蓝桥杯)
c++·蓝桥杯·dfs·回溯算法
remember_me.9 个月前
蓝桥杯十四届c/c++省赛:飞机降落、接龙数列(Java版可AC代码)
java·蓝桥杯·动态规划·dfs·回溯算法
我是镜流的狗10 个月前
39. 组合总和(力扣LeetCode)
c++·算法·leetcode·回溯算法
WenGyyyL10 个月前
第七章回溯_组合
java·c++·算法·回溯算法