回溯算法:适用于不重复的排列组合
题目1:
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例:
void backtrack(vector<vector<int>>& res, vector<int>& output, int first, int len) {
// 所有数都填完了
if (first == len) {
res.emplace_back(output);
return;
}
for (int i = first; i < len; ++i) { //从first开始而不是first+1开始是因为,第一个与第一个交换表示第一个被使用,即排序数组第一个元素是原来第一个元素,是有意义的
// 动态维护数组
swap(output[i], output[first]);
// 继续递归填下一个数
backtrack(res, output, first + 1, len);
// 撤销操作
swap(output[i], output[first]);
}
}
//0 1 2
//b((012),0)
//b((012),1), b((102),1) b((210),1)
//b((012),2) b((021),2) b((102),2) b((120),2) b((210),2) b((201),2)
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int> > res;
backtrack(res, nums, 0, nums.size());
return res;
}
算法的思想为:
从前到后一直不重复的换,如0123
先让0分别和0123互换(0与0互换代表初始状态,也是一种状态,因此有意义)产生0123,1023,2103,3120四种情况。
0是第一位,换过了,因此从第二层递归第二位开始换:
如0123从1开始换:产生0123,0213,0321
第三层递归从第三个数开始换:
如0123从2开始换:产生0123,0132
最后一层递归first=len,因此不用换,到此为止,填充结果:0123,0132
因此共432=24种情况。
情况公式为 n!
题目2:
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的不同组合数少于 150 个。
题目来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/combination-sum
void add(vector<vector<int>>& result, vector<int>& onerst, vector<int>& candidates, int target, int posi,int left) { //[2,3,6,7], 7
if (posi >= candidates.size()) {
return;
}
if (left == candidates[posi]) {
onerst.push_back(candidates[posi]);
result.push_back(onerst);
onerst.pop_back(); //注意无论何时插入数据都要记得弹出
result;
}
if (left > 0) { //不能用else if ,因为即便插入当前数据已经满足要求,也不能保证不插入这个数据不会有其他满足的情况
add(result, onerst, candidates, target, posi + 1, left);
onerst.push_back(candidates[posi]);
add(result, onerst, candidates, target, posi, left-candidates[posi]);
onerst.pop_back(); //注意无论何时插入数据都要记得弹出
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> result;
vector<int> onerst;
add(result, onerst, candidates, target, 0, target);
return result;
}
算法思想同上:
1,注意每一步数据插入都会影响之后数据,
2,注意插入数据后记得弹出
3,注意考虑所有情况