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)