赞
踩
回溯法是一种以递归去遍历各种情况的搜索方式,搜索过程可抽象成遍历一棵N叉树的遍历过程,集合的大小构成树的宽度,递归的深度就构成了树的深度,遍历中会枚举所有情况,实际上就是一个暴力搜索的过程,有时候迭代遍历多层for循环做不出来的时候,可用回溯法做出来。
从大类来说可解决两大类问题,再细分下来是五小类问题:
注:组合问题并不要求元素按一定顺序,排列问题要求元素按一定顺序。
参考文章:回溯法总结篇
解决一个回溯问题,实际上就是一个决策树的宾利过程,对于回溯树的一个结点,需要思考三个问题:
结束条件(到达决策树底层,无法再做选择的条件);路径(已做出的选择);选择列表(当前可做的选择)。
vector<bool> visitied; // 排列问题时,使用visited判定是否访问过
vector<type> path; // 存储某一条路径的情况
vector<vector<type>> res; // 结果集
void backtracking(参数1, 参数2, ...) {
if(终止条件) {
存放结果;
return ;
}
for (选择: 本层集合中元素(树中结点孩子的数量就是集合大小)) {
处理结点;
backtracing(路径, 选择列表);
回溯,回退至处理结点之前的状况;
}
}
i > startIndex && nums[i] == nums[i - 1]
参考文章:回溯算法理论基础、回溯算法解题套路框架
组合问题就是遍历一颗N叉树的过程,最终获取树中的所有叶节点。
一个集合求组合的话,需要用stratIndex
来控制遍历起始下标。如果是多个集合取组合,各个集合间相互不影响,则不需要satatIndex
。
去重: startIndex
用于选择路径,来保证是否去重结果集。当startIndex
为i
时,结果集中可含有相同的数;当startIndex
为i+1
时,结果集中不含有相同的数。
剪枝: 让数组按递增顺序排列,设置判定上界为n - (k - nums.size())
,其中n
为数组大小,单个k
结果大小。上界以外的数,由于在之后遍历的时候一定会不符合单个结果要求个数,因此直接剪枝跳过。
集合中元素不同,单个结果内元素仅能被选一次,结果间不重复
114、【回溯算法】leetcode ——77. 组合:回溯法+剪枝优化(C++版本):选择路径时,更新下标数为i + 1
。
115、【回溯算法】leetcode ——216.组合总和III:回溯法+剪枝优化(C++版本):增加一个和是否为n的判定条件
集合中元素有相同,单个结果内同一元素可被选多次,结果间不重复
117、【回溯算法】leetcode ——39. 组合总和:回溯法+剪枝优化(C++版本) :先按升序排列,选择路径时,更新下标数为i
。
集合中元素有相同,单个结果内各个元素仅能被选一次,结果间不重复
118、【回溯算法】leetcode ——40. 组合总和 II:回溯法+剪枝优化(C++版本):使用i > startIndex && nums[i] == nums[i - 1]
来去重判定,选择路径时,更新下标为i + 1
。
分割问题的整体过程与组合问题相似,都是依次选择某一元素再遍历,最终获取叶结点,不同之处在于分割问题在每次递归遍历前,要判定分割条件
,当满足分割条件时,将元素进行分割,然后再递归的向下进行遍历。
119、【回溯算法】leetcode ——93. 复原 IP 地址(C++版本):字符换成数字判定是否符合有效IP位
如果把遍历过程看作遍历一颗树,那么子集问题就是收集树中所有的结点
。而组合问题和分割问题则是获取树的所有叶节点
。
递增序列
123、【回溯算法】leetcode ——491. 递增子序列:unordered_set去重和int数组去重(C++版本):保留序列原始顺序,获取递增子序列(相当于是找到符合某一条的子集),难点在于如何在无序数组中去重。
排列问题的特点是区分元素顺序
,即同一个元素占据不同的位置,会代表不一样的结果。而组合问题的特点是不区分元素顺序
,即同一个元素,只要在这个结果中,无论占据那个位置都认为相同的。
含重复数字需去重排序问题
125、【回溯算法】leetcode ——47.全排列 II:visited去重(C++版本):树层去重和树枝都可以,本题树层去重效率更高
N皇后经典问题(二维信息判定)
49、【图】N-皇后问题:二维信息判定(C/C++版):按行遍历、设置列、副、主对角线记录
解数独(三维信息判定)
126、【回溯算法】leetcode ——37. 解数独:三维信息判定(C++版本):判定行、列、3x3小单元内是否冲突,其中小单元判定的起始位置使用先除3再乘3的方式,保证从每个小单元起始位置遍历。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。