代码随想录第二十九天:491.递增子序列、46.全排列、47.全排列 II

491.递增子序列

这道题要求不能有相同的递增子序列,子集+去重,但是又要求是递增的子序列,所以不能对这个给定的集合进行排序,因此不能用之前题目中的去重逻辑

class Solution(object):
    def findSubsequences(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []
        self.backtracking(nums, 0, res, [])
        return res

    def backtracking(self, nums, startindex, res, path):
        # 集合中无元素剩余时终止,相当于遍历完了,所以可以不写
        if len(path) > 1:  # 要求递增子序列中至少两个元素
            res.append(path[:])
        uset = set()  # 每一层中,遇到重复的就要去掉,用set来去重,每一层遍历完之后set重置为空
        for i in range(startindex, len(nums)):
            if (path and nums[i] < path[-1]) or nums[i] in uset:  # 如果子序列不是递增了或本层有重复的了,就跳过
                continue
            uset.add(nums[i])
            path.append(nums[i])
            self.backtracking(nums, i+1, res, path)
            path.pop()

46.全排列

全排列问题中[1, 2]和[2, 1]算两个集合,因此不需要用startindex了,每次都从0开始选择没被选择的元素。所以排列问题需要一个used数组,标记已经选择的元素。

class Solution(object):
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []
        used = [False]*len(nums)
        self.backtracking(nums, used, res, [])
        return res

    def backtracking(self, nums, used, res, path):
        if len(path) == len(nums):
            res.append(path[:])
            return
        for i in range(0, len(nums)):
            if used[i] == True: # 遇到被选择过的就跳过
                continue
            path.append(nums[i])
            used[i] = True
            self.backtracking(nums, used, res, path)
            used[i] = False
            path.pop()

47.全排列 II

这题中包含重复数字,因此是去重+全排列

class Solution(object):
    def permuteUnique(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums.sort()
        res = []
        used = [False]*len(nums)
        self.backtracking(nums, [], res, used)
        return res

    def backtracking(self, nums, path, res, used):
        if len(path) == len(nums):
            res.append(path[:])
            return
        for i in range(0, len(nums)):
            if (i > 0 and nums[i] == nums[i-1] and used[i-1] == False) or used[i] == True:
                continue     # 这边改为used[i-1] == True也可以,True是在树枝上去重,而False是对树层去重,树枝去重更麻烦
            path.append(nums[i])
            used[i] = True
            self.backtracking(nums, path, res, used)
            used[i] = False
            path.pop()

题解:代码随想录代码随想录代码随想录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值