(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()
相关推荐
卷卷的小趴菜学编程7 天前
算法篇----递归回溯
c++·算法·递归·回溯算法·暴力搜索·floodfill算法·二叉树深搜
漫随流水8 天前
leetcode回溯算法(46.全排列)
数据结构·算法·leetcode·回溯算法
漫随流水9 天前
leetcode回溯算法(93.复原IP地址)
数据结构·算法·leetcode·回溯算法
漫随流水9 天前
leetcode回溯算法(90.子集Ⅱ)
数据结构·算法·leetcode·回溯算法
漫随流水9 天前
leetcode回溯算法(491.非递减子序列)
数据结构·算法·leetcode·回溯算法
漫随流水10 天前
leetcode回溯算法(78.子集)
数据结构·算法·leetcode·回溯算法
漫随流水11 天前
leetcode回溯算法(131.分割回文串)
数据结构·算法·leetcode·回溯算法
漫随流水14 天前
leetcode回溯算法(17.电话号码的字母组合)
数据结构·算法·leetcode·回溯算法
漫随流水14 天前
leetcode回溯算法(39.组合总和)
数据结构·算法·leetcode·回溯算法
漫随流水15 天前
leetcode回溯算法(77.组合)
数据结构·算法·leetcode·回溯算法