非递减子序列 491. 非递减子序列
给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况
数组的子序列是由数组删除一些元素(也可能不删除)而不改变剩余元素顺序形成的序列。
例如,[4,6,7] 是数组 [4,5,6,7] 的一个子序列。
题目数据保证答案中至少有一个非递减子序列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution : def backtracking (self,nums,index,path,result ): if len (path) > 1 : result.append(path[:]) set_ = set () for i in range (index,len (nums)): if (path and nums[i] < path[-1 ]) or nums[i] in set_: continue path.append(nums[i]) set_.add(nums[i]) self .backtracking(nums,i+1 ,path,result) path.pop() def findSubsequences (self, nums: List [int ] ) -> List [List [int ]]: result = [] self .backtracking(nums,0 ,[],result) return result
主要是加了一个set来实现树层去重,注意set是在每一层递归开始时创建的
不能直接排序
nums,因为排序会改变元素的相对顺序,导致错误的结果,因此这里想实现返回的是非递减子序列就要在path加元素的时候判断是否比path[-1]大
然后还有个有意思的就是实现树层去重(就是在分层的时候根节点相同的树枝就不要了),结合这几天的学习我对这种题目的理解就是————
for循环是分树枝,回溯函数是生长枝条 ,所以在for循环里面判断是否去重,而不是在回溯函数里面判断是否去重。
那如何实现树层去重呢? 那就是用
set_这个集合来实现,并且这是个局部变量(作用域在当前层,也就是在每个回溯函数中),每一层递归都会创建当层的集合,用来记录当层已经使用过的元素,从而实现树层去重。
全排列 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]]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution : def backtracking (self,nums,used,path,result ): if len (path) == len (nums): result.append(path[:]) for i in range (len (nums)): if used[i]: continue path.append(nums[i]) used[i] = True self .backtracking(nums,used,path,result) path.pop() used[i] = False def permute (self, nums: List [int ] ) -> List [List [int ]]: result = [] used = [False ]*len (nums) self .backtracking(nums,used,[],result) return result
在排列问题上就不再需要startIndex了,因为排列是有序的,所以每次都从0开始遍历 但是选过的元素就不能再选了,所以需要一个used数组来记录哪些元素已经被选过了(类似组合问题的剪枝,每调用回溯函数就剪一条边)
全排列 II 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]]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution : def backtracking (self,nums,used,path,result ): if len (path) == len (nums): result.append(path[:]) set_ = set () for i in range (len (nums)): if nums[i] in set_ or used[i]: continue path.append(nums[i]) used[i] = True set_.add(nums[i]) self .backtracking(nums,used,path,result) used[i] = False path.pop() def permuteUnique (self, nums: List [int ] ) -> List [List [int ]]: result = [] used = [False ] * len (nums) self .backtracking(nums,used,[],result) return result
主要是在排列的基础上加了一个set来实现树层去重,注意set是在每一层递归开始时创建的,就是结合上道题的排列,和上上道题的去重。
实际上一个uesd也行,用之前的排序加
used[i]和
used[i-1]判断是否相同来实现树层去重
感觉先自己做再看视频就激情四射了