Combination Sum

本文详细解析了一道经典的算法题目——组合求和。通过递归方法,从给定的无重复数字集合中找出所有可能的组合,使得这些组合的元素之和等于目标数值。文章通过具体的例子展示了算法的实现过程,包括如何避免重复组合,以及如何设定搜索范围来提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

Given a set of candidate numbers (candidates(without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

The same repeated number may be chosen from candidates unlimited number of times.

Note:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

Example 1:

Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
  [7],
  [2,2,3]
]

Example 2:

Input: candidates = [2,3,5], target = 8,
A solution set is:
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]

解题思路:这题使用递推的方法思路会比较简单,题目输入是一个数字集合,我们知道集合中的数是没有顺序的,也没有重复,我们需要做的是从集合中取若干个数相加等于target,集合中的每个数可以使用多次,那么我们可以每次从集合中取一个数,与target相减,直到target减为0,就得到一组答案,但如果每次都是遍历整个集合,结果就会出现重复的答案。所以我们需要设定一个条件,即只能从当前位置向后找。以例2为例,如果我们当前的取的是3,那么我们在寻找下一个数的时候只能从3开始找,也即备选项只有3和5,2不能再出现,否则会出现[2,3,3]和[3,2,3]和[3,3,2]三个答案。

代码如下:

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
  		//用于记录最后的结果
		vector<vector<int>> res ;

		auto size = candidates.size() ;
		//记录每个单独的解
        vector<int> ar;

        findResult(candidates,0,target,ar,res) ;
        
        return res ;
    }

    /*
    *	findResult(const vector<int> candidates,int it, int target,vector<int>& ar,vector<vector<int>>& res)
    *	candidates:输入的集合
    *	it:当前的起始位置,只能从it向后寻找下一个加数
    *	target:当前目标数,当为0时表示找到了一组答案
    *	ar:用于存储一组解
    *	res:目标答案
    */
    void findResult(const vector<int> candidates,int it, int target,vector<int>& ar,vector<vector<int>>& res){

        for( int i=it;i<candidates.size();i++ ){

        	if( target >= candidates[i] ){

        		ar.push_back(candidates[i]) ;
        		target -= candidates[i] 

        		if( target == 0 ){
        			res.push_back(ar) ;
        		}
                
        		findResult(candidates,i,target,ar,res) ;

        		ar.pop_back() ;
        		target += candidates[i] ;
        	
        	}
        }
        
        // return ar ;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值