当前位置:   article > 正文

【力扣hot100】刷题笔记Day17

【力扣hot100】刷题笔记Day17

前言

  • 今天竟然不用开组会!天大的好消息,安心刷题了

46. 全排列 - 力扣(LeetCode)

  • 回溯(排列)

      1. class Solution:
      2. def permute(self, nums: List[int]) -> List[List[int]]:
      3. # 回溯
      4. def backtrack():
      5. if len(path) == len(nums):
      6. res.append(path[:]) # 如果path长度达到要求,收集结果,注意python要拷贝res
      7. return
      8. for i in range(len(nums)):
      9. if used[i] == 0: # 遍历所有没用过的
      10. used[i] = 1
      11. path.append(nums[i])
      12. backtrack()
      13. path.pop() # 撤销
      14. used[i] = 0 # 撤销
      15. # 可变对象在函数中可以直接改不需要作为参数,也不需要写self,只有赋值需要
      16. # 比如:递归里self.res= max(self.res,l+r)需要用self或递归里nonlocal res声明
      17. n = len(nums)
      18. used = [0] * n
      19. path = []
      20. res = []
      21. backtrack()
      22. return res
  • 回溯(交换填充)

      1. class Solution:
      2. def permute(self, nums: List[int]) -> List[List[int]]:
      3. def backtrack(first = 0):
      4. # 所有数都填完了
      5. if first == n:
      6. res.append(nums[:])
      7. for i in range(first, n):
      8. # 动态维护数组
      9. nums[first], nums[i] = nums[i], nums[first]
      10. # 继续递归填下一个数
      11. backtrack(first + 1)
      12. # 撤销操作
      13. nums[first], nums[i] = nums[i], nums[first]
      14. n = len(nums)
      15. res = []
      16. backtrack()
      17. return res

 78. 子集 - 力扣(LeetCode)

  • 回溯(组合)

      1. class Solution:
      2. def subsets(self, nums: List[int]) -> List[List[int]]:
      3. def backtrack(start=0):
      4. res.append(path[:]) # 每到一个节点就传一次答案
      5. # if start == n: return # 下面的for循环隐含这个终止条件
      6. for i in range(start, n):
      7. path.append(nums[i])
      8. backtrack(i+1) # 注意这里传入的是i+1
      9. path.pop()
      10. n = len(nums)
      11. res = []
      12. path = []
      13. backtrack(0)
      14. return res

17. 电话号码的字母组合 - 力扣(LeetCode) 

  • 回溯(不同集合的组合)

      1. class Solution:
      2. def letterCombinations(self, digits: str) -> List[str]:
      3. def backtrack(index = 0):
      4. if index == len(digits):
      5. res.append("".join(path)) # 不用传复制因为已经新建字符串了
      6. return
      7. s = mp[int(digits[index])] # 取出对应数字的字符串
      8. for c in s:
      9. path.append(c)
      10. backtrack(index+1)
      11. path.pop()
      12. if len(digits) == 0:
      13. return []
      14. mp = ['', '', 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz'] # 下标号码映射字符串
      15. path = []
      16. res = []
      17. backtrack()
      18. return res

39. 组合总和 - 力扣(LeetCode) 

  • 回溯(排序剪枝)

      1. class Solution:
      2. def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
      3. path = []
      4. res = []
      5. n = len(candidates)
      6. def backtrack(start, target):
      7. if target < 0: return # 剪枝返回上一层,后面更大的数就没必要减了
      8. if target == 0:
      9. res.append(path[:])
      10. return
      11. for i in range(start, n):
      12. path.append(candidates[i])
      13. backtrack(i, target-candidates[i]) # 传i而不是i+1说明当前数可以重复选
      14. path.pop()
      15. candidates.sort() # 剪枝,排序后大的数在后面选择优先级低
      16. backtrack(0, target)
      17. return res

 22. 括号生成 - 力扣(LeetCode)

  • 回溯(组合)

    • 这个题解结合官解就能看懂了,主要在于括号合法性判断上
      1. class Solution:
      2. def generateParenthesis(self, n: int) -> List[str]:
      3. if n <= 0: return n
      4. res = []
      5. def backtrack(path, left, right):
      6. # 两种情况需要剪枝
      7. # 1.左括号多于n了:((((
      8. # 2.右括号多于左括号:())
      9. if left > n or right > left: return
      10. if len(path) == 2 * n: # 因为括号都是成对出现的
      11. res.append(path)
      12. return
      13. backtrack(path + '(', left + 1, right) # 生成一个加一个
      14. backtrack(path + ')', left, right + 1)
      15. backtrack('', 0, 0)
      16. return res

后言

  • 今天就到这吧,还有其他事情,感觉回溯还不熟练,脑子里模拟不太出来,待会去看看代码随想录再熟悉熟悉 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/176758
推荐阅读
相关标签
  

闽ICP备14008679号