基本介绍
回溯法实际上是暴力搜索的算法,常和递归一起使用,适用于排列,组合,子集,解数独,棋盘,切割问题。
能用回溯算法处理通常能画成n叉树的结构。树的宽度用for循环,深度用递归。
模板
void backtracking(参数)
{
if(终止条件)
{
收集结果
return ;
}
for(横向遍历)
{
处理节点
递归处理
回溯处理
}
}
注意:
- 参数传递如果传入固定的值可以不用传入地址,但是如果在算法中要更新它的值要传入地址!!!!!!
- 回溯处理就是让同一层递归下处理的值不变,如果没有回溯处理,则值会改变,会积累!!
例子:78. 子集【leetcode】
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入:nums = [0]
输出:[[],[0]]
提示:
1 <= nums.length <= 10
-10 <= nums[i] <= 10
nums 中的所有元素 互不相同
class Solution {
public:
void ff(vector<vector<int> >& ans,vector<int>& v,vector<int>& nums,int x,int idx)
{
if(v.size()==x)
{
ans.push_back(v);
return ;
}
for(int i=idx;i<nums.size();i++)
{
v.push_back(nums[i]);
ff(ans,v,nums,x,i+1);
v.pop_back();
}
}
vector<vector<int>> subsets(vector<int>& nums)
{
vector<vector<int> >ans;
vector<int>v;
sort(nums.begin(),nums.end());
for(int i=0;i<=nums.size();i++) ff(ans,v,nums,i,0);
return ans;
}
};