leetcode - 39. Combination Sum

    xiaoxiao2021-03-26  12

    39. Combination Sum

    Given a set ofcandidate numbers (C) (without duplicates) and atarget number (T), find all unique combinations in C wherethe candidate numbers sums to T.

    The same repeatednumber may be chosen from C unlimited number of times.

    Note:

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

    For example,given candidate set [2, 3, 6, 7] and target 7

     

    给定一个数组,然后再给定一个target的值,选择数组中的若干个元素的值求和,使得这个和的值等于target,然后记录下这些元素并返回。

    PS:每个元素可以多次使用,并且相同的元素组合只需记录一次,如[1,2,3][3,2,1]等价,只需返回[1,2,3]

    [2,1] target = 5

    返回结果:

    [1,1,1,1,1] ,[1,1,1,2] , [1,2,2]

     

     

    算法思想

             可以采用深度优先遍历(dfs),考虑优化dfs,也就是剪枝,大大加快了算法的速度。

    因为查找几个元素是否满足和等于target,至少就需要二重遍历,所以复杂度是大于O(n)的,那么可以考虑先将数组排序,再进行dfs,利用vector模拟栈操作。

     

     

     

    步骤

    1.  初始化当前和记为s,当前栈为v。

    2.  若s等于target,则把v中的所有元素记录,并回溯。

    3.  若s不等于targe,从头开始遍历数组,更新s的值,新的s的值等于旧的s值加上当前遍历到的元素:

    a)        若新的s值大于target的值,回溯,s值等于旧的s。//剪枝

    b)        若新的s值小于等于target的值,就跳到2。//dfs

    private : int s; vector<int> v; vector< vector<int> >result; public: void dfs(vector<int> ca,int target , int now){ // cout << "s -> " << s << " " << target<< endl; if(s == target){ result.push_back(v); // cout << "r -> "; } for(int i = now ; i < ca.size() ; i++){ if(s + ca[i] <= target){ // if <= target v.push_back(ca[i]); s += ca[i]; // cout << "ca[i] -> " << ca[i] << endl; dfs(ca,target,i); s -= v.back(); v.pop_back(); // cout << endl << " ret "<<endl; } else{ return; } }//for(i) } vector<vector<int>> combinationSum(vector<int>& ca, int target) { sort(ca.begin(),ca.end()); for(int i = 0; i < ca.size() ; i++){ s = 0; s += ca[i]; v.push_back(ca[i]); dfs(ca,target,i); v.pop_back(); }//for(i) return result; }

    转载请注明原文地址: https://ju.6miu.com/read-450240.html

    最新回复(0)