分析:此题有两个坑,一是这里的n个数是任意给定的,不一定是:1,2,3...n,所以可能有重复的数(如果有重复的数怎么处理?);二是不要求你输出所有和为s的全部组合,而只要求输出和为s的k个数的组合。
举个例子,假定n=6,这6个数为:1 2 1 3 0 1,如果要求输出和为3的全部组合的话,
- 1 2
- 1 2 0
- 0 3
- 1 1 1
- 1 1 1 0
而题目加了个限制条件,若令k=2,则只要求输出:[{1,2}, {0,3}] 即可。
#include <iostream> #include<list> #include<vector> using namespace std; #define SUM 20 #define SIZE 10 #define K 3 #define HASHSIZE 9 list<int> mylist; vector<int> hashvector; void initRandom(int* arr) { srand(unsigned(time(0))); for (int i = 0; i < SIZE; i++) { arr[i] = rand() % 10; } for (int i = 0; i < SIZE; i++) { cout << " " << arr[i]; } cout << endl; } int getCurHash() { int hash = 0; for (list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it) { hash |= (1 << *it); } return hash; } void sumOfkNum(int sum, int*arr, int i, bool &flag) { if (sum <= 0 || i == SIZE) { return; } if (sum == arr[i] && mylist.size() == K - 1) { int hash = getCurHash() | (1 << arr[i]); if (find(hashvector.begin(), hashvector.end(), hash) == hashvector.end()) { hashvector.push_back(hash); for (list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it) { cout << *it << "+"; } cout << arr[i] << endl; } else { return; } } else { if (mylist.size() > K) { return; } mylist.push_back(arr[i]); sumOfkNum(sum - arr[i], arr, i + 1, flag); mylist.pop_back(); sumOfkNum(sum, arr, i + 1, flag); } } int main() { int* arr = new int[SIZE]; bool flag = false; initRandom(arr); sumOfkNum(SUM, arr, 0, flag); if (hashvector.empty()) { cout << "no result" << endl; } return 0; }