回溯法 (递归的一种)
回溯算法的递归使用以及剪枝策略。
回溯法:一种通过探索所有可能的候选解来找出所有的解的算法。如果候选解被确认不是一个解(或者至少不是最后一个解),回溯算法会通过在上一步进行一些变化抛弃该解,即回溯并且再次尝试。
正规写法:
python
t = [] |
简便写法:
python
def dps(i,tmp): ## i表示当前的位置,tmp列表,临时列表,选中则放入,不选中则返回 |
如果涉及剪枝或避免重复元素:
- 先进行排序,保证重复的元素放在一起
- 然后回溯选取下一个节点的时候判断一下是否和前面的相同,相同的则不用再继续遍历,相当于剪枝;不同则要继续遍历。
简便写法:
python
nums.sort() ## 需要先进行排序 |
值传递、引用传递、浅拷贝、深拷贝
值传递和引用传递
不可变类型在传递参数时都是传值形式,如 int,str,tuple 类型。
可变类型在传递参数时都是引用传递,如 list,set,dict 类型。指向的都是同一块内存地址
值传递:当元素被赋予新值或者修改值的时候,是指向了一个新的对象,和原对象无关。当原值没有对象再指向它,就会被 python 的 GC 回收。
引用传递:指向的都是同一块内存地址,一旦改变值,所有指向这个内存地址的都会改变
拷贝的内置函数
copy () 浅拷贝:不拷贝对象的内容,只拷贝子对象的引用,原数据改变,则子对象会改变
deepcopy () 深拷贝:对子对象的内存也会拷贝一份,对子对象的修改不会影响源对象,原始数据的改变不会影响深拷贝
a = b: 引用传递
a.copy ():浅拷贝
copy.copy (a):浅拷贝
copy.deepcopy (a):深拷贝
区别 nums 和 nums [:]
nums [:] = nums [0:len (nums)] 可以使用 [:] 来拷贝全部元素
nums [:] 在计算机中是新分配了一个地址,当其改变时是不会影响到原数据的,相同的是原数据的改变也不会影响数值的改变。
相关练习
LeetCode 中相关的题目:
- 78. 子集: 可以使用回溯法,时间复杂度为 O (n*2^n), 空间复杂度为 O (n).
- 90. 子集 II: 解集不能包含重复的子集(回溯算法 + 剪枝)
- 46. 全排列:回溯法,划分左右
- 47. 全排列 II:回溯法 + 剪枝,可以使用标记列表和回溯相结合 (以空间换时间)
题目详细描述
子集
python
class Solution: |
子集 II
python
class Solution: |
全排列:将题目给定的数组划分成左右两个部分,左边表示已经填过的数,右边表示代填的数,在回溯的时候动态维护这个数组
python
class Solution: |
全排列 II:
python
class Solution: |