回溯本质上还是递归,用到了深度优先搜索的思想,是一种暴力搜索法。
关于回溯问题,有一套答题模板,我称之为回溯三部曲。
第一步 确定回溯函数伪代码
void trackback(int argc,char * argv)
参数问题还是需要具体问题具体分析,我们可以先写主函数逻辑,用到什么参数在加上去。
第二步 回溯函数终止条件
需要一个一维数组存放符合条件的结果,二维数组存放符合条件的集合
vector<vector<int>> result;
vector<int> path
if(判断条件)
{
存放结果;
return;
}
图片出处力扣,感谢大佬。
第三步 回溯问题遍历过程伪代码如下:
这里通常需要一个数组记录同一树枝上的元素是否使用过,
vector<bool> used
for(循环)
{
处理子节点;
backtrack();
回溯,撤销处理结果
}
最后整体的回溯算法框架如下:
void trackback()
{
if(判断条件)
{
保存结果;
return;
}
for(循环)
{
处理子节点;
trackback();
回溯;
}
}
46 全排列
题目描述见力扣,按照上面的三部曲,一步步确定函数逻辑。
1.确定回溯函数
2.递归终止条件
这里题目要求是全排列,那么终止条件就是path数组大小等于目标数组大小,具体视题目要求。
3.回溯函数遍历
解释下,为什么需要pop_back,因为我们找到了一个满足题目要求的数组后,需要把尾部元素删除,才能存放新的元素,不然就会出现尾大不掉的情况,也就是尾部一直增加的情况。
最后整体的函数为:
后续再补充
参考:力扣