引用 剑指offer 38 Tom也要offer
①画递归树
如果我们固定了(选择了)某个数,那么他的下一层的选择列表就是——除去这个数以外的其他数!!\比如,第一次选择了2,那么他的下一层的选择列表只有1和3;如果选择了3,那么他的下一层的选择列表只有1和2,那么这个时候就要引入一个used数组来记录使用过的数字,算法签名如下
void backtrack(vector<int>& nums,vector<bool>&used,vector<int>& path)//你也可以把used设置为全局变量
②找结束条件
if(path.size()==nums.size())
{
res.push_back(path);
return;
}
③找准选择列表
for(int i=0;i<nums.size();i++)
{
if(!used[i])//从给定的数中除去用过的,就是当前的选择列表
{
}
}
④判断是否需要剪枝
不需要剪枝,或者你可以认为,!used[i]已经是剪枝
⑤做出选择
for(int i=0;i<nums.size();i++)
{
if(!used[i])//从给定的数中除去用过的,就是当前的选择列表
{
path.push_back(nums[i]);//做选择
used[i]=true;//设置当前数已用
backtrack(nums,used,path);//进入下一层
}
}
⑥撤销选择
整体代码如下
void backtrack(vector<int>& nums,vector<bool>&used,vector<int>& path)//used初始化为false
{
if(path.size()==nums.size())
{
res.push_back(path);
return;
}
for(int i=0;i<nums.size();i++)//从给定的数中除去,用过的数,就是当前的选择列表
{
if(!used[i])//如果没用过
{
path.push_back(nums[i]);//做选择
used[i]=true;//设置当前数已用
backtrack(nums,used,path);//进入下一层
used[i]=false;//撤销选择
path.pop_back();//撤销选择
}
}
}