代码随想录算法训练营第二十九天丨491. 非递减子序列、46. 全排列、47. 全排列 II

491. 非递减子序列

无优化版本:

使用used对本层进行去重,没有优化的版本:

class Solution:
    def findSubsequences(self, nums: List[int]) -> List[List[int]]:
        res = []
        path = []
        length = len(nums)

        def backtrack(start, used):
            if len(path) > 1 and all([path[i] <= path[i + 1] for i in range(len(path) - 1)]):
                res.append(path[:])
            if start >= length:
                return
            
            for i in range(start, length):
                if nums[i] in used:
                    continue
                else:
                    path.append(nums[i])
                    backtrack(i + 1,[])
                    path.pop()
                used.append(nums[i])

        backtrack(0,[])
        return res

哈希优化版本:

class Solution:
    def findSubsequences(self, nums: List[int]) -> List[List[int]]:
        res = []
        path = []
        length = len(nums)

        def backtrack(start):
            if len(path) > 1:
                res.append(path[:])
            
            hash_table = [0] * 201
            
            for i in range(start, length):
                if hash_table[nums[i]]:
                    continue
                if path and nums[i] < path[-1]:
                    continue
                path.append(nums[i])
                backtrack(i + 1)
                path.pop()
                hash_table[nums[i]] = 1

        backtrack(0)
        return res

*在这个版本中,实际上在维护哈希表时忘记给nums[i]加上100,但是也顺利AC了,这时因为在python中索引可以为负,负索引会让数组从后向前找元素,也没有重复地使用了整个哈希表。

46. 全排列

自己写的版本:

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        res = []
        path = []
        length = len(nums)

        def backtrack():
            if len(path) == len(nums):
                res.append(path[:])
                return

            for i in range(length):
                if nums[i] in path:
                    continue
                path.append(nums[i])
                backtrack()
                path.pop()
        
        backtrack()
        return res

优化版:

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        res = []
        path = []
        used = [False] * len(nums)
        length = len(nums)

        def backtrack():
            if len(path) == len(nums):
                res.append(path[:])
                return

            for i in range(length):
                if used[i]:
                    continue
                path.append(nums[i])
                used[i] = True
                backtrack()
                path.pop()
                used[i] = False
        
        backtrack()
        return res

优化版本使用used数组代替检查 if nums[i] in path: 将检查元素是否在path数组里的复杂度从O(n)降到了O(1)。

47. 全排列 II

综合之前学的,可以写出代码:

class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        res = []
        path = []
        nums.sort()
        length = len(nums)
        used = [0] * length

        def backtrack():
            if len(path) == length:
                res.append(path[:])
                return
            
            for i in range(length):
                if used[i] or (i > 0 and used[i - 1] and nums[i] == nums[i -1]):
                    continue
                path.append(nums[i])
                used[i] = 1
                backtrack()
                path.pop()
                used[i] = 0
        backtrack()
        return res

今日总结:

之前学到的方法今天又全部用上了,全排列使用used数组且可以同时进行去重。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值