• 算法day29|491,46,47


    491.递增子序列

    1. class Solution:
    2. def findSubsequences(self, nums: List[int]) -> List[List[int]]:
    3. used = [False]*len(nums)
    4. result = []
    5. nums.sort()
    6. def backtracking(nums,path,startindex,used):
    7. nonlocal result
    8. if len(path)>1:
    9. result.append(path[:])
    10. for i in range(startindex,len(nums)):
    11. if i>0 and nums[i] == nums[i-1] and used[i-1]==False:
    12. continue
    13. else:
    14. path.append(nums[i])
    15. used[i] = True
    16. backtracking(nums,path,i+1,used)
    17. path.pop()
    18. used[i] = False
    19. backtracking(nums,[],0,used)
    20. return result

    问题1:如何按照顺序?(一般是直接增序)

    1. class Solution:
    2. def findSubsequences(self, nums: List[int]) -> List[List[int]]:
    3. result = []
    4. def backtracking(nums,path,startindex):
    5. nonlocal result
    6. if len(path) > 1:
    7. result.append(path[:])
    8. #每进入新的一层循环,都自动清空
    9. useset = set()
    10. for i in range(startindex,len(nums)):
    11. #没有在useset合集中,新加的数要比path里面的最后一个元素大
    12. #len(path) 防止溢出
    13. if (len(path)>0 and nums[i]< path[-1]) or (nums[i] in useset):
    14. continue
    15. else:
    16. path.append(nums[i])
    17. useset.add(nums[i])
    18. backtracking(nums,path,i+1)
    19. path.pop()
    20. backtracking(nums,[],0)
    21. return result

    z代码随想录

    重点:不能对集合进行排序,怎么做呢?

    任何分析,都需要画个图出来观察

    题目要求:

    都是递增:所以有个条件就是path中最后一个数要比新加入的数小

    删除同一层节点的重复元素?使用一个set存放,如果同一层里面的数存在,就跳过

    视频讲解:回溯算法精讲,树层去重与树枝去重 | LeetCode:491.递增子序列_哔哩哔哩_bilibili

    二刷(未ac)

    1. var findSubsequences = function(nums) {
    2. let result = []
    3. const isValid = function(arr){
    4. for(let i = 0;i<arr.length-1;i++){
    5. if(arr[i+1]<arr[i]){
    6. return false
    7. }
    8. }
    9. return true
    10. }
    11. const backtracking = function(nums,path,startindex){
    12. let used = []
    13. // when end?
    14. if(path.length>nums.length){
    15. return
    16. }
    17. if(path.length > 1){
    18. if(isValid(path)){
    19. result.push([...path])
    20. }
    21. }
    22. for(let i = startindex;i<nums.length;i++){
    23. if(used[nums[i]]){
    24. continue
    25. }
    26. used[nums[i]] = true
    27. path.push(nums[i])
    28. backtracking(nums,path,i+1)
    29. path.pop()
    30. }
    31. }
    32. backtracking(nums,[],0)
    33. return result
    34. };

    46.全排列

    组合和排列问题差别在:

    排列不需要在意集合中的顺序,顺序不同也算不同

    组合需要算集合中的顺序,顺序不同不算不同

    所以在这里不需要节点去重。

    但是需要使用used集合记录一下每个数是否取过 

    1. class Solution:
    2. def permute(self, nums: List[int]) -> List[List[int]]:
    3. result = []
    4. used = [False]*len(nums)
    5. def backtracking(nums,path,used):
    6. nonlocal result
    7. #终止条件
    8. if len(nums) == len(path):
    9. result.append(path[:])
    10. return
    11. #单层遍历逻辑
    12. for i in range(0,len(nums)):
    13. #如果这个数使用过的话,就跳过
    14. if used[i] == True:
    15. continue
    16. else:
    17. path.append(nums[i])
    18. used[i] = True
    19. backtracking(nums,path,used)
    20. path.pop()
    21. used[i] = False
    22. backtracking(nums,[],used)
    23. return result

    代码随想录

    视频讲解:组合与排列的区别,回溯算法求解的时候,有何不同?| LeetCode:46.全排列_哔哩哔哩_bilibili
     

    二刷(未ac)

    1. var permute = function(nums) {
    2. let result = []
    3. let used = new Array(nums.length).fill(0)
    4. const backtracking = function(nums,path,used){
    5. // 终止条件
    6. if(path.length === nums.length){
    7. result.push([...path])
    8. }
    9. for(let i = 0;i<nums.length;i++){
    10. if(used[i]===1){continue}
    11. path.push(nums[i])
    12. used[i] = 1
    13. backtracking(nums,path,used)
    14. used[i] = 0
    15. path.pop()
    16. }
    17. }
    18. backtracking(nums,[],used)
    19. return result
    20. };

    47.全排列 II

    本题 就是我们讲过的 40.组合总和II 去重逻辑 和 46.全排列 的结合,可以先自己做一下,然后重点看一下 文章中 我讲的拓展内容。 used[i - 1] == true 也行,used[i - 1] == false 也行

    1. class Solution:
    2. def permuteUnique(self, nums: List[int]) -> List[List[int]]:
    3. result = []
    4. used = [False]*len(nums)
    5. nums.sort()
    6. def backtracking(nums,used,path):
    7. nonlocal result
    8. if len(nums) == len(path):
    9. result.append(path[:])
    10. return
    11. #单层逻辑
    12. for i in range(0,len(nums)):
    13. if used[i] == True:
    14. continue
    15. elif (i>0 and nums[i] == nums[i-1] and used[i-1] == False):
    16. continue
    17. else:
    18. path.append(nums[i])
    19. used[i] = True
    20. backtracking(nums,used,path)
    21. used[i] = False
    22. path.pop()
    23. backtracking(nums,used,[])
    24. return result

    代码随想录

    重点:

    记得排序啊,重复元素去重,太重要了,这个细节

    视频讲解:回溯算法求解全排列,如何去重?| LeetCode:47.全排列 II_哔哩哔哩_bilibili

    二刷(ac)

    1. var permuteUnique = function(nums) {
    2. nums.sort((a,b)=>(a-b))
    3. let result = []
    4. let used = new Array(nums.length).fill(0)
    5. const backtracking = function(nums,path,used){
    6. if(path.length === nums.length){
    7. result.push([...path])
    8. return
    9. }
    10. for(let i =0;i<nums.length;i++){
    11. if(i>0 && nums[i-1]===nums[i]&&used[i-1]===1){
    12. continue
    13. }
    14. if(used[i]===1){
    15. continue
    16. }
    17. path.push(nums[i])
    18. used[i]=1
    19. backtracking(nums,path,used)
    20. used[i]=0
    21. path.pop()
    22. }
    23. }
    24. backtracking(nums,[],used)
    25. return result
    26. };

     

  • 相关阅读:
    HBase导出建表语句
    【电压质量】提高隔离电源系统的电压质量(Simulink实现)
    LeetCode 刷题 [C++] 第279题.完全平方数
    MySQL数据库 -- 入门篇
    【语音识别】动态时间规整算法(RTW)语音识别系统【含GUI Matlab源码 341期】
    SQLlite
    apache虚拟主机头的实现方式
    HTML网页设计结课作业 web课程设计网页规划与设计 网页设计成品DW静态网页 Web大学生网页成品 web网页设计期末课程大作业
    前端js篇
    【历史上的今天】12 月 3 日:世界上第一条短信;Fortran 语言之父诞生;百度贴吧上线
  • 原文地址:https://blog.csdn.net/weixin_42173016/article/details/128010724