网站改名 备案,伍佰亿营销型网站,搜狗seo快速排名公司,网站开发服务的协议LeetCode 热题 100_组合总和#xff08;58_39#xff09; 题目描述#xff1a;输入输出样例#xff1a;题解#xff1a;解题思路#xff1a;思路一#xff08;递归#xff08;回溯#xff09;#xff09;#xff1a; 代码实现代码实现#xff08;思路一#xff08… LeetCode 热题 100_组合总和58_39 题目描述输入输出样例题解解题思路思路一递归回溯 代码实现代码实现思路一递归回溯以思路一为例进行调试 题目描述
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target 找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同则两种组合是不同的。
对于给定的输入保证和为 target 的不同组合数少于 150 个。
输入输出样例
示例 1 输入candidates [2,3,6,7], target 7 输出[[2,2,3],[7]] 解释 2 和 3 可以形成一组候选2 2 3 7 。注意 2 可以使用多次。 7 也是一个候选 7 7 。 仅有这两种组合。
示例 2 输入: candidates [2,3,5], target 8 输出: [[2,2,2,2],[2,3,3],[3,5]]
示例 3 输入: candidates [2], target 1 输出: []
提示 1 candidates.length 30 2 candidates[i] 40 candidates 的所有元素 互不相同 1 target 40
题解
解题思路
思路一递归回溯
1、使用回溯的方法解组合问题时最好的方法是画出递归树进行分析。 通过递归树不难分析出 ①、递归出口sumtarget记录答案回溯 或者 sumtarget回溯 我们可以记录path中的总和为sum通过sum与target的比较来判断。也可以使用target-path数组中的元素与0进行比较来判断其效果相同。 ②、递归体sum target(查找可能的组合)
2、复杂度分析 ① 时间复杂度O(S)其中 S 为所有可行解的长度之和也就是递归树的节点数。 ② 空间复杂度O(target)。除答案数组外空间复杂度取决于递归的栈深度也就是上图递归树的深度在最差情况下需要递归 O(target) 层。
代码实现
代码实现思路一递归回溯
class Solution {
private://记录其中一个组合vectorint path;//记录所有满足组合总和的组合vectorvectorint ans;//递归回溯计算组合总和void backtracking(vectorint candidates, int target,int startIndex){//为目标数 “target” 的一个组合存储到ans中if (target0){ ans.emplace_back(path);return;}//当path中的数据大于“target”返回path无需再添加元素需减少元素if (target0) return;//注意这里i的开始位置是为了避免出现“全排列”类型的重复for (int i startIndex; i candidates.size(); i){path.emplace_back(candidates[i]);//继续添加其他元素注意一个元素可以重复添加所以startIndexibacktracking(candidates,target - candidates[i],i);//回溯和path.emplace_back(candidates[i])对应path.pop_back();}}public:vectorvectorint combinationSum(vectorint candidates, int target) {//清空ans和path中的数据防止上次调用存在数据残留ans.clear();path.clear();//递归回溯计算组合总和backtracking(candidates,target,0);return ans;}
};以思路一为例进行调试
#includeiostream
#include vector
using namespace std;class Solution {
private://记录其中一个组合vectorint path;//记录所有满足组合总和的组合vectorvectorint ans;//递归回溯计算组合总和void backtracking(vectorint candidates, int target,int startIndex){//为目标数 “target” 的一个组合存储到ans中if (target0){ ans.emplace_back(path);return;}//当path中的数据大于“target”返回path无需再添加元素需减少元素if (target0) return;//注意这里i的开始位置是为了避免出现“全排列”类型的重复for (int i startIndex; i candidates.size(); i){path.emplace_back(candidates[i]);//继续添加其他元素注意一个元素可以重复添加所以startIndexibacktracking(candidates,target - candidates[i],i);//回溯和path.emplace_back(candidates[i])对应path.pop_back();}}public:vectorvectorint combinationSum(vectorint candidates, int target) {//清空ans和path中的数据防止上次调用存在数据残留ans.clear();path.clear();//递归回溯计算组合总和backtracking(candidates,target,0);return ans;}
};int main(int argc, char const *argv[])
{vectorint candidates{2,3,5};int target8;//计算组合总和Solution s;vectorvectorint anss.combinationSum(candidates,target);//输出计算的组合总和for (int i 0; i ans.size(); i){cout[;for (int j 0; j ans[i].size(); j){coutans[i][j];if (j!ans[i].size()-1){cout ;}}cout];}return 0;
}LeetCode 热题 100_组合总和58_39)原题链接 欢迎大家和我沟通交流(✿◠‿◠)