题目:组合
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
For example,
If n = 4 and k = 2, a solution is:
[ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
题意:
给定两个整数n和k,返回所有由1到n之间的数构成的k个数的组合。
思路一:
递归实现。观察上面给出的例子可以看出,每个元素均需要与其之后的所有元素建立组合。则按照以上给出的例子写出代码即可。如果n=6,k=4,则组合如下所示:
1234
1235
1236
1245
1246
1256
1345
1346
1356
1456
2345
2346
2356
2456
3456
代码:C++版:136ms
class Solution { public: vector<vector<int>> combine(int n, int k) { vector<vector<int>> res; vector<int> path; dfs(n, k, 1, 0, path, res); return res; } private: //start表示开始的数。cur表示对现在有的数位进行计数,数位长度达到k位时,将单个组合放入res中 static void dfs(int n, int k, int start, int cur, vector<int> &path, vector<vector<int>> &res) { if (cur == k) { res.push_back(path); } for (int i=start; i<=n; ++i) { path.push_back(i); dfs(n, k, i+1, cur+1, path, res); path.pop_back(); } } };
思路二:
迭代版。初始化一个values数组存储1到n之间的所有值,再维护一个select数组用来存储1到n中的数是否被选中,由选中的数组合成为一个组合,利用prev_permutation(select.begin(),select.end())函数调整select数组值,则代码中只需要根据select数组选择对应的数字构成组合即可。如果n=6,k=4,则组合如下所示:
value集合数组值 | select集合数组值 | one集合数组值 |
123456 | 111100 | 1234 |
123456 | 111010 | 1235 |
123456 | 111001 | 1236 |
123456 | 110110 | 1245 |
123456 | 110101 | 1246 |
123456 | 110011 | 1256 |
123456 | 101110 | 1345 |
123456 | 101101 | 1346 |
123456 | 101011 | 1356 |
123456 | 100111 | 1456 |
123456 | 011110 | 2345 |
123456 | 011101 | 2346 |
123456 | 011011 | 2356 |
123456 | 010111 | 2456 |
123456 | 001111 | 3456 |
代码:C++版:100ms
class Solution { public: vector<vector<int>> combine(int n, int k) { vector<int> values(n); //将values数组初始化为1~n之间递增的数 iota(values.begin(), values.end(), 1); //执行结果为values={1,2,3,4,5...n} vector<bool> select(n, false); //存储n个数字是否被使用 fill_n(select.begin(), k, true); //将select数组前k个数都置为true,因为组合第一个数是依次递增的,如123..k。 vector<vector<int>> result; do{ vector<int> one(k); //定义一个长度为k的集合 for (int i = 0, index = 0; i < n; ++i) if (select[i]) one[index++] = values[i]; //将初始化的123...k放入集合数组中 result.push_back(one); //将该组合放入返回集合数组中 } while(prev_permutation(select.begin(), select.end())); //select集合数组是否有上一个全排列 return result; } };