回溯
回溯法一般是在 数据结构(一般是数组)中递归搜索,集合的大小构成了树的宽度,递归的深度构成的树的深度。一般使用回溯的n都很小,同时需要遍历所有情况。本质是爆搜,只是比枚举稍微强点。
①组合问题
去重逻辑
当数据结构中有重复元素时,为了避免重复需要去重。同层去重,同枝可以不去重
- 改变排序规则
在排序后面加上自编函数,结构类似于下,可自定义排序顺序
//此时绝对值小的排在前面
static bool cmp(int a, int b){
return abs(a) < abs(b);
}
sort(容器.begin(), 容器.end());
排序+下一层的遍历从上层收纳元素的下一个开始+遍历时全局数组st记录元素是否同枝遍历过
如果遍历时前后两元素相同:
1) st为真,说明当前重复元素是同枝,可以加入当前元素到集合中
2) st为假,说明当时已经跳出一个树枝,进入另一枝同一层(同一位置),此时需要去重。
- 不改变排序顺序
在每一层开一个局部变量数组st记录这层已经使用过的元素,每遍历到一个新元素就在st中找一下有没有用过。
②子集问题
子集问题本质上也要用组合问题,记录生成组合的每一步就生成了子集。子集问题同样可以使用去重逻辑的模板,但是由于子集中元素不重复,可以不使用st数组,遇到前后两元素相同就跳过即可。
③全排列问题
全排列不同于组合的点在于规定了元素排列的顺序,这就要求每一层的循环从下标0开始,同时需要开全局数组st记录同枝已经遍历过元素达到全排列。此时去重也只需用st数组,此时同枝和同层去重也没在区别,但是同层去重的效率更高。
贪心
对于区间问题的贪心,还是要从实际目的出发,也就是在当前排序下能否或者怎样取得局部最优解以达到整体最优解。相比于动态规划,贪心不强调状态转移,而又要求最优解,此时需要一点转化。