代码随想录算法训练营第四期第二十九天 | 491.递增子序列、46.全排列、47.全排列 II

491.递增子序列

# 给你一个整数数组nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中至少有两个元素 。你可以按任意顺序返回答案。
# 数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。
#
# 示例1:
# 输入:nums = [4, 6, 7, 7]
# 输出:[[4, 6], [4, 6, 7], [4, 6, 7, 7], [4, 7], [4, 7, 7], [6, 7], [6, 7, 7], [7, 7]]
#
# 示例2:
# 输入:nums = [4, 4, 3, 2, 1]
# 输出:[[4, 4]]
class Solution:
    def findSubsequences(self, nums: [int]):
        # 树层上去重,树枝上不去重
        res = []
        path = []
        def backtracking(nums,startindex): # 用startindex来避免重复
            # 子集类问题可以不写终止条件
            if len(path) > 1:
                res.append(path[:])
            use = [] # 是否使用过
            for i in range(startindex,len(nums)):
                # 加入数据条件有三,1.当前数比path最后一个数大,2.path不为空,3.未出现在use里
                if (path and nums[i] < path[-1] )or nums[i] in use:
                        continue
                path.append(nums[i])
                use.append(nums[i])
                backtracking(nums, i+1)
                path.pop()
        backtracking(nums,0)
        return res


if __name__ == '__main__':
    nums = [4,6,7,7]
    tmp = Solution()
    res = tmp.findSubsequences(nums)
    res.sort()
    print(res)

46.全排列

# 给定一个不含重复数字的数组nums ,返回其所有可能的全排列 。你可以按任意顺序返回答案。
#
# 示例1:
# 输入:nums = [1, 2, 3]
# 输出:[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
#
# 示例2:
# 输入:nums = [0, 1]
# 输出:[[0, 1], [1, 0]]
#
# 示例3:
# 输入:nums = [1]
# 输出:[[1]]
class Solution:
    def permute(self, nums: [int]):
        res = []
        path = []
        # 自己写的,居然不需要索引
        def backtracking(nums):
            if len(path) == len(nums):
                res.append(path[:])
                return
            for i in range(len(nums)):
                if nums[i] not in path:
                    path.append(nums[i])
                    backtracking(nums)
                    path.pop()
        backtracking(nums)
        return res

    def permute2(self, nums: [int]):
        res = []
        path = []
        # 看了5分钟,了解了index和used,先来试一下
        used = [0] * len(nums)
        def backtracking(nums,index):
            if len(path) == len(nums):
                res.append(path[:])
                return
            for i in range(index,len(nums)):
                if not used[i]: # 避免取重复元素
                    path.append(nums[i])
                    used[i] = 1
                    backtracking(nums,0) # 每次遍历都是从头开始
                    used[i] = 0
                    path.pop()
        backtracking(nums,0)
        return res

    def permute3(self, nums: [int]):
        # 卡哥的写法
        res = []
        path = []
        # 看了5分钟,了解了index和used,先来试一下
        used = [0] * len(nums)
        def backtracking(nums,used):
            if len(path) == len(nums):
                res.append(path[:])
                return
            for i in range(0,len(nums)):
                if used[i] == 1:
                    continue
                used[i] = 1
                path.append(nums[i])
                backtracking(nums, used)  # 每次遍历都是从头开始
                used[i] = 0
                path.pop()
        backtracking(nums,used)
        return res


if __name__ == '__main__':
    nums = [1, 2, 3]
    # nums.remove(nums)
    tmp = Solution()
    # res = tmp.permute(nums)
    # res = tmp.permute2(nums)
    res = tmp.permute3(nums)
    print(res)

47.全排列 II

# 给定一个可包含重复数字的序列nums ,按任意顺序返回所有不重复的全排列。
#
# 示例1:
# 输入:nums = [1, 1, 2]
# 输出:
# [[1, 1, 2],
#  [1, 2, 1],
#  [2, 1, 1]]
#
# 示例2:
# 输入:nums = [1, 2, 3]
# 输出:[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
class Solution:
    def permuteUnique(self, nums: [int]):
        res = []
        path = []
        used = [0] * len(nums)
        def backtracking(nums,used):
            if len(path) == len(nums):
                tmp = path[:]
                if tmp not in res:
                    res.append(tmp)
                return
            for i in range(0,len(nums)):
                if used[i] == 1:
                    continue
                used[i] = 1
                path.append(nums[i])
                backtracking(nums,used)
                used[i] = 0
                path.pop()
        backtracking(nums,used)
        return res

    def permuteUnique2(self, nums: [int]):
        res = []
        path = []
        used = [0] * len(nums)
        nums.sort()
        def backtracking(nums,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] == 0: # used[i-1]数层去重
                    continue
                if used[i] == 0: # 取过的信息不取
                    path.append(nums[i])
                    used[i] = 1
                    backtracking(nums,used)
                    path.pop()
                    used[i] = 0
        backtracking(nums,used)
        return res



if __name__ == '__main__':
    nums = [1, 1, 2]
    # nums.remove(nums)
    tmp = Solution()
    # res = tmp.permuteUnique(nums)
    res = tmp.permuteUnique2(nums)
    print(res)

你可能感兴趣的:(算法,leetcode,数据结构)