46. 数组全排列I 不含重复数字的数组 nums
,返回其 所有可能的全排列 。
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
def backtrace(nums, used, depth, path, res, long):
if depth == long:
res.append(path[:])
return
for i in range(len(nums)): #### 对每个元素作为首字母 的情况 考虑 用回溯的方法解决特定首字符的所有情况
if not used[i]:
path.append(nums[i])
used[i] = True
backtrace(nums, used, depth+1, path, res, long)
path.pop() #### 弹出最后一个元素 【这两步 都是对应的 回溯操作之前的 逆变换操作】
used[i] = False ####
if not nums: return
long = len(nums)
res = []
used = [False for _ in range(long)]
backtrace(nums, used, 0, [], res, long)
return res
47. 数组全排列 II 含有重复数字 https://leetcode-cn.com/problems/permutations-ii/
### 基于全排列I 的模板 回溯的基础之上 【进行剪枝】
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
def backtrace(nums, used, depth, long, path, res):
if depth ==long:
res.append(path[:])
return
for i in range(long):
if not used[i]:
if i>0 and nums[i]==nums[i-1] and not used[i-1]: ##### 改加 2
continue
# else:
path.append(nums[i])
used[i]= True
backtrace(nums, used, depth+1, long, path, res)
path.pop()
used[i]= False
if not nums:return
res = []
long = len(nums)
used = [False for _ in range(long)]
nums.sort() ##### 改加 1
backtrace(nums, used, 0, long, [], res)
return res
77. 数组组合 给定两个整数 n
和 k
,返回范围 [1, n]
中所有可能的 k
个数的组合。
################################### 再回到 上面 全排列的 模板 改动 三处
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
def backtrace(nums, long, depth, path, used, res,k):
# if depth==k:
if len(path)==k: ################## 1 #
res.append(path[:])
return
# for i in range(long):
for i in range(depth, long): ################## 2 #
if not used[i]:
path.append(nums[i])
used[i]=True
# backtrace(nums, long, depth+1, path, used, res,k)
backtrace(nums, long, i+1, path, used, res,k) ################## 3 #
path.pop()
used[i]=False
nums = [i for i in range(1,n+1)]
long = len(nums)
depth= 0
res = []
used = [False for _ in range(long)]
backtrace(nums, long, depth, [], used, res,k)
return res
38. 字符串的排列 字符串的全排列 不含重复I 和 含重复II
### 先写【字符串的全排列】 与数组的全排列 不同之处在于 【 path.apend(s[i]) VS path+=s[i] 】 【 path.pop() VS path = path[:-1] 】
#---------------------------------------------------------------------------------------------------------------
class Solution:
def permutation(self, s: str) -> List[str]:
def backtrace(s, path, depth, used, long, res):
if depth == long:
res.append(path[:])
return
for i in range(long): ### 错1 整个板块 ---已经漏写
if not used[i]:
used[i]=True
path+=s[i]
backtrace(s, path, depth+1, used, long, res) ### 错2 这三句 【位置在if语句内 】【不是 并列if语句 更不是 并列for语句】
used[i]=False
path = path[:-1] ### 错3 已经漏写
if not s:return
res = []
long= len(s)
used= [False for _ in range(long)]
backtrace(s, '', 0, used, long, res)
return res
### N刷 (PART II)
### 以上 只是粗暴的全排列 不符合题意---- 也没有考虑排列结果的重复问题 ------ 以下 考虑 结果的重复问题 ----
#---------------------------------------------------------------------------------------------------------------
### 再写【字符串的全排列II】
### 本题 考虑重复 剪枝 办法 【backtrace(sorted(s), '', 0, used, long, res) if i>0 and s[i]==s[i-1]and not used[i-1]:continue 】
#---------------------------------------------------------------------------------------------------------------
class Solution:
def permutation(self, s: str) -> List[str]:
def backtrace(s, path, depth, used, long, res):
if depth == long:
res.append(path[:])
return
for i in range(long):
if not used[i]:
if i>0 and s[i]==s[i-1]and not used[i-1]:continue ###改动1:: if i>0 and s[i]==s[i-1] : continue 就不行
used[i]=True
path+=s[i]
backtrace(s, path, depth+1, used, long, res)
used[i]=False
path = path[:-1]
if not s:return
res = []
long= len(s)
used= [False for _ in range(long)]
# backtrace(s, '', 0, used, long, res)
backtrace(sorted(s), '', 0, used, long, res) ###改动2::
return res
784. 字母大小写全排列 字母大小写转换 并且全排列
# N刷 前两题的 【全排列】 --感觉不适合这里 内部换顺序 【组合】 --- 选取部分数据 # 没有思路 【大小写全排列】---架构类似于【组合】
# ######################################################
class Solution:
def letterCasePermutation(self, s: str) -> List[str]:
def backtrace(path, index):
if len(path)==len(s):
res.append(path[:])
return
if s[index].isdigit():
backtrace(path+s[index], index+1)
else:
if s[index].islower():
backtrace(path + s[index].upper(), index+1) ### upper() 括号 也忘了
else:
backtrace(path + s[index].lower(), index+1)
backtrace(path+s[index], index+1)
res = []
backtrace("", 0) ### backtrace([], 0) 这里的path 是字符串 不是列表
return res