【转载】Combination Sum

Combination Sum

 

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.
  • Elements in a combination (a1, a2, … ,ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
  • 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] 

 

  1 /** 整理的提交代码
  2  * 处理复杂度为
  3  * 主要思路:与Combination Sum不同之处在与每轮每个候选数字只能取一次,所以下次递归时考虑的当前元素的之后的元素
  4  *     所以这次在index中存放的下标是当前元素的下一个位置,以便递归时直接跳过上次考察过的元素,避免重复考察。
  5  *     但是在记录结果时需要回复记录在index中的下标。
  6  *       回溯法http://www.leetcode.com/2010/09/print-all-combinations-of-number-as-sum.html
  7  * 提交结果: 
  8  * (Judge Small) 
  9  * Run Status: Accepted! 
 10  * Program Runtime: 4 milli secs (基本在几毫秒)
 11  * Progress: 22/22 test cases passed. 
 12  * (Judge Large) 
 13  * Run Status: Accepted!
 14  * Program Runtime: 144 milli secs    (基本稳定在一百四十几毫秒左右)
 15  * Progress: 172/172 test cases passed.
 16  */
 17 #include <vector>
 18 #include <algorithm>
 19 #include <functional>
 20 #include <iostream>
 21 using namespace std;
 22 
 23 class Solution {
 24 private:
 25     const int index_count;
 26     vector<vector<int> > results;
 27 public:
 28     Solution() : index_count(10000) {};
 29     // index记录当前找到的候选数字,n表示当前正在找第几个,n是index的下标不是candidates的下标
 30     void backtrace(int target, int sum, vector<int> &candidates, int index[], int n)
 31     {
 32         if (sum > target)
 33         {
 34             return;    // 回溯
 35         }
 36         if (sum == target)
 37         {
 38             vector<int> result;
 39             for (int i = 1; i <= n; ++i)
 40             {
 41                 result.push_back(candidates[index[i]-1]);    // 这里需要减一,因为下面每次记录索引时加了1    
 42             }
 43             results.push_back(result);
 44             return;    // 此处可以不加,如果不加return由于都是正整数,到下面的计算时会多进行一次无用的递归。
 45         }
 46 
 47         // 深度搜索,为了避免重复,每次从当前候选项索引到结尾,上面的i=index[n]可以看出
 48         for (int i = index[n]; i < candidates.size(); ++i)
 49         {
 50             index[n+1] = i+1;    // 记录当前考察的候选项索引并加一,下次考察是跳过上次考察过的元素,每轮每个元素值考察一次
 51             backtrace(target, sum+candidates[i], candidates, index, n+1);
 52         }
 53     }
 54     vector<vector<int> > combinationSum2(vector<int> &candidates, int target) {
 55         // Start typing your C/C++ solution below
 56         // DO NOT write int main() function
 57         sort(candidates.begin(), candidates.end());
 58 
 59         int *index = new int[index_count];
 60         memset(index, 0, sizeof(int)*index_count);
 61 
 62         results.clear();    // 提交到leetcode的测试系统上必须添加,它应该是使用一个对象测试所有测试用例。
 63         backtrace(target, 0, candidates, index, 0);
 64 
 65         delete[] index;
 66 
 67         // 去重
 68         vector<vector<int> >::iterator end = results.end();  
 69         sort(results.begin(), end, less<vector<int> >());
 70         vector<vector<int> >::iterator new_end = unique(results.begin(), results.end());
 71         results.erase(new_end, end);
 72 
 73         return results;
 74     }
 75 };
 76 
 77 int main()
 78 {
 79     vector<int> candidates;
 80     int number;
 81     cout << "input candidates: ";
 82     while (cin >> number)
 83     {
 84         candidates.push_back(number);
 85     }
 86 
 87     // 清除缓冲区
 88     cin.sync();
 89     cin.clear();
 90 
 91     int target;
 92     cout << "input target: ";
 93     cin >> target;
 94 
 95     vector<vector<int> > result;
 96     Solution s;
 97     result = s.combinationSum2(candidates, target);
 98 
 99     for (size_t i = 0; i < result.size(); ++i)
100     {
101         for (size_t j = 0; j < result[i].size(); ++j)
102         {
103             cout << result[i][j] << ' ';
104         }
105         cout << endl;
106     }
107     cout << endl;
108 
109     return 0;
110 }

 

 

 

 
posted @ 2015-05-25 22:12  HelloWaston  阅读(182)  评论(0编辑  收藏  举报