40. Combination Sum II

来源:互联网 发布:apache运行python 编辑:程序博客网 时间:2024/06/05 00:08

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

Each number in C may only be used once in the combination.

Note:

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

For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8
A solution set is: 

[  [1, 7],  [1, 2, 5],  [2, 6],  [1, 1, 6]]

  这道题是39. Combination Sum的变体,同样是给出一个目标数target(T),在candidates数组(C)中找到和为T的所有可能的组合,主要区别就是candidates数组中的数字不能重复选择。

  在39.Combination Sum的代码中,如果只是单纯地把递归调用的第二个参数right(或left)从i改成i - 1(或i + 1),就会出现重复的组合,例如,若C为(2, 2, 3, 3, 6, 7),则运行结果为[(2, 2, 3), (2, 2, 3), (7)],可见,(2, 2, 3)重复了一次,因为两个(2, 2, 3)中的3是不一样的,一个是C[2],另一个是C[3]。因此,需要做出一定的改动(第5行和第21行),在遍历的过程中,当发现该数字C[i]与前驱(backtrack2)或后继(backtrack1)是一样的,则直接跳过,不进行任何判断,因为以C[i]这个数字开头的遍历早已在其前驱(backtrack2)或后继(backtrack1)进行过一次。

  从本质上讲backtrack1和backtrack2没有什么区别,只是遍历方向不一样,但有趣的是,在39. Combination Sum中用两种函数分别提交得到的Run time相差还是挺大的,分别是29ms和42ms,backtrack2用的时间长些。然而更有趣的是,在本题中,用两种函数得到的Run time分别是22ms和13ms,这次backtrack1用的时间更长些。

  算法的时间复杂度仍然难以计算,但可以知道,在极端情况下——candidates数组中所有数字不重复且它们的和小于target,时间复杂度为O(n!)。

  代码如下:

class Solution {public:void backtrack1(vector<int> com, int right, int target) {for (int i = right; i >= 0; i--) {if (i < right && candidates[i] == candidates[i + 1]) continue;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 - 1, target - candidates[i]);}}}void backtrack2(vector<int> com, int left, int target) {for (int i = left; i < candidates.size(); i++) {if (i > left && candidates[i] == candidates[i - 1]) continue;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 + 1, target - candidates[i]);}}}vector<vector<int>> combinationSum2(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
原创粉丝点击