排列 组合

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值