39. Combination Sum

来源:互联网 发布:网络社交软件 编辑:程序博客网 时间:2024/05/12 14:29

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

The same repeated number 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
A solution set is: 

[  [7],  [2, 2, 3]]


  题目的意思是,给出一个目标数target(T),在candidates数组(C)中找到和为T的所有可能的组合,需要注意的一点是,数组中的数字可以重复选择。

  这道题可以用回溯的方法解决,若从后往前进行遍历,对于数组中的每个数candidates[i],有如下三种情况:

  ① candidates[i] < target。则将candidates[i]选入com中,然后递归调用backtrack1函数,注意此时target要减去candidates[i],形成一个与原问题类似的子问题,即从candidates[0]到candidates[i]中找到和为target - candidates[i]的所有可能的组合。

  ② candidates[i] = target。说明找到一个可能的组合,将com选入res中。

  ③ candidates[i] > target。这种情况就不必继续探讨了,直接continue。

  当然也可以从前往后遍历(backtrack2函数),只需在backtrack1函数的基础上稍微修改即可,因此这两个函数实质上并没有什么区别,对同一个样例来说,运行过程中两个函数被调用的次数一模一样。但有趣的是,用两种函数去提交,得到的Run time相差还是挺大的,backtrack1用了29ms,而backtrack2用了42ms,不清楚为什么两个时间复杂度一样的函数的Run time相差这么大。

  至于算法的时间复杂度,跟样例有很大的关系,难以计算。

  代码如下:

class Solution {public:void backtrack1(vector<int> com, int right, int target) {for (int i = right; i >= 0; i--) {if (candidates[i] > target) continue;else if (candidates[i] == target) {vector<int> tmp = com;tmp.push_back(candidates[i]);res.push_back(tmp);}else {vector<int> tmp = com;tmp.push_back(candidates[i]);backtrack1(tmp, i, target - candidates[i]);}}}void backtrack2(vector<int> com, int left, int target) {for (int i = left; i < candidates.size(); i++) {if (candidates[i] > target) break;else if (candidates[i] == target) {vector<int> tmp = com;tmp.push_back(candidates[i]);res.push_back(tmp);}else {vector<int> tmp = com;tmp.push_back(candidates[i]);backtrack2(tmp, i, target - candidates[i]);}}}vector<vector<int>> combinationSum(vector<int>& candidates, int target) {sort(candidates.begin(), candidates.end());this->candidates = candidates;//backtrack1(vector<int>(0), candidates.size() - 1, target);backtrack2(vector<int>(0), 0, target);return res;}private:vector<int> candidates;vector<vector<int>> res;};


0 0
原创粉丝点击