【力扣hot100】刷题笔记Day17

前言

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

46. 全排列 - 力扣(LeetCode)

回溯(排列)

复制代码
```python
class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        # 回溯
        def backtrack():
            if len(path) == len(nums):
                res.append(path[:])  # 如果path长度达到要求,收集结果,注意python要拷贝res
                return 
            for i in range(len(nums)):
                if used[i] == 0:  # 遍历所有没用过的
                    used[i] = 1
                    path.append(nums[i])
                    backtrack()
                    path.pop()  # 撤销
                    used[i] = 0  # 撤销
        # 可变对象在函数中可以直接改不需要作为参数,也不需要写self,只有赋值需要
        # 比如:递归里self.res= max(self.res,l+r)需要用self或递归里nonlocal res声明
        n = len(nums)
        used = [0] * n
        path = []
        res = []
        backtrack()
        return res
```

回溯(交换填充)

复制代码
```python
class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        def backtrack(first = 0):
            # 所有数都填完了
            if first == n:  
                res.append(nums[:])
            for i in range(first, n):
                # 动态维护数组
                nums[first], nums[i] = nums[i], nums[first]
                # 继续递归填下一个数
                backtrack(first + 1)
                # 撤销操作
                nums[first], nums[i] = nums[i], nums[first]
        
        n = len(nums)
        res = []
        backtrack()
        return res
```

78. 子集 - 力扣(LeetCode)

回溯(组合)

复制代码
```python
class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        def backtrack(start=0):
            res.append(path[:])  # 每到一个节点就传一次答案
            # if start == n: return  # 下面的for循环隐含这个终止条件
            for i in range(start, n):
                path.append(nums[i])
                backtrack(i+1)  # 注意这里传入的是i+1
                path.pop()
        n = len(nums)
        res = []
        path = []
        backtrack(0)
        return res
```

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

回溯(不同集合的组合)

复制代码
```python
class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        def backtrack(index = 0):
            if index == len(digits):
                res.append("".join(path))  # 不用传复制因为已经新建字符串了
                return
            s = mp[int(digits[index])]  # 取出对应数字的字符串
            for c in s:
                path.append(c)
                backtrack(index+1)
                path.pop()
        if len(digits) == 0:
            return []
        mp = ['', '', 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz']  # 下标号码映射字符串
        path = []
        res = []
        backtrack()
        return res
```

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

回溯(排序剪枝)

复制代码
```python
class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        path = []
        res = []
        n = len(candidates)
        def backtrack(start, target):
            if target < 0: return    # 剪枝返回上一层,后面更大的数就没必要减了
            if target == 0:
                res.append(path[:])
                return
            for i in range(start, n):
                path.append(candidates[i])
                backtrack(i, target-candidates[i])  # 传i而不是i+1说明当前数可以重复选
                path.pop()
        candidates.sort()  # 剪枝,排序后大的数在后面选择优先级低
        backtrack(0, target)
        return res
```

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

回溯(组合)

  • 这个题解结合官解就能看懂了,主要在于括号合法性判断上
复制代码
```python
class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        if n <= 0: return n
        res = []

        def backtrack(path, left, right):
            # 两种情况需要剪枝
            # 1.左括号多于n了:((((
            # 2.右括号多于左括号:())
            if left > n or right > left: return
            if len(path) == 2 * n:  # 因为括号都是成对出现的
                res.append(path)
                return
            backtrack(path + '(', left + 1, right)  # 生成一个加一个
            backtrack(path + ')', left, right + 1)
        backtrack('', 0, 0)

        return res
```

后言

  • 今天就到这吧,还有其他事情,感觉回溯还不熟练,脑子里模拟不太出来,待会去看看代码随想录再熟悉熟悉
相关推荐
我不会起名字3228 分钟前
一天一道算法题(34):回溯法的经典例题(子集)
java·数据结构·python·算法·golang·深度优先·力扣
IT小白杨29 分钟前
社媒多账号运营的环境隔离:一张图谱模型,解释清“为什么换IP还是被连坐“
经验分享·笔记·矩阵·指纹浏览器
ThornArmor44 分钟前
重铸1996|肉体渲染:关节的裂缝:分段模型积木拼装与未成熟的 RSP 矩阵骨骼动画形变
c语言·汇编·c++·python·硬件架构·游戏机
毕业设计7031 小时前
(免费领源码)基于Python的博物馆研学活动管理系统的设计与实现22724- java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
python·mysql·随机森林·pycharm·django·flask·推荐算法
kyrie_sakura1 小时前
python学习笔记15 -- Anaconda,Jupyter,numpy
python·学习·jupyter·numpy
测试老哥2 小时前
接口测试的测试用例应该怎么写?
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·接口测试
Zenova EdgeOS2 小时前
Python 工业边缘 redis-py 异步实战
开发语言·redis·python
huang5791472 小时前
哈希算法的抗碰撞机制与安全性增强策略4
算法
caoerzhong2 小时前
JeeWMS 开源仓库管理系统权限与域验证解析:Java WMS 如何把数据权限管到仓、货主与人
java·python·开源·vue
一木 之林2 小时前
Miniconda 安装与 Jupyter 使用入门
ide·python·jupyter