# LeetCode:Combinations

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],
]

 1 class Solution {
2 public:
3     vector<vector<int> > combine(int n, int k) {
4         vector<vector<int> >res;
5         vector<int>tmpres;
6         helper(1,n,k,tmpres,res);
7         return res;
8     }
9
10     //从[left, right]范围内选取k个数，tmpres是一个临时组合
11     void helper(int left, int right, int k, vector<int> &tmpres, vector<vector<int> >&res)
12     {
13         if(right-left+1 < k)return;
14         if(k == 0)
15         {
16             res.push_back(tmpres);
17             return;
18         }
19         //选择left
20         tmpres.push_back(left);
21         helper(left+1, right, k-1, tmpres, res);
22         tmpres.pop_back();
23         //不选择left
24         helper(left+1, right, k, tmpres, res);
25     }
26 };

• 选取第一个元素：第一个元素只能从[1,2,3,4]中选取，因为如果第一个元素选择5或者6，就不能保证选取的3个元素组合满则上面的限制
• 假设第一个元素选取的是2，那么第二个元素只能从[3,4,5]中选取，原因同上
• 假设第二个元素选取的是4，那么第三个元素只能从[5,6]中选取，原因同上
 1 class Solution {
2 public:
3     vector<vector<int> > combine(int n, int k) {
4         vector<vector<int> >res;
5         vector<int>tmpres;
6         helper(1,n,k,tmpres,res);
7         return res;
8     }
9
10     //从[left, right]范围内选取k个数，tmpres是一个临时组合
11     void helper(int left, int right, int k, vector<int> &tmpres, vector<vector<int> >&res)
12     {
13         if(k == 0)
14         {
15             res.push_back(tmpres);
16             return;
17         }
18         for(int i = left; i <= right-k+1; i++)
19         {
20             tmpres.push_back(i);
21             helper(i+1, right, k-1, tmpres, res);
22             tmpres.pop_back();
23         }
24     }
25 };

class Solution {
public:
vector<vector<int> > combine(int n, int k) {
vector<vector<int> >res;
vector<vector<int> >vec(1);
for(int i = 1; i <= n; i++)
{
int len = vec.size();
vector<int> tmp;
for(int j = 0; j < len; j++)
{
tmp = vec[j];
tmp.push_back(i);
if(tmp.size() == k)res.push_back(tmp);
else vec.push_back(tmp);
}
}
return res;
}
};

 1 class Solution {
2 public:
3     vector<vector<int> > combine(int n, int k) {
4         vector<vector<int> >res;
5         vector<int>tmpres;
6         for(int bit = (1<<k) - 1; bit <= (1<<n) - (1<<(n-k)); bit = NextN(bit))//注意bit的最大值为(1<<n) - (1<<(n-k)即选择n的前k个
7         {
8             tmpres.clear();
9             for(int i = 0; i < n; i++)
10             {
11                 if(bit & (1<<i))
12                     tmpres.push_back(i+1);
13             }
14             res.push_back(tmpres);
15         }
16         return res;
17     }
18     //返回最小的、比N大的整数M，使得M与N的二进制表示中有相同数目的1
19     int NextN(int N)
20     {
21         int x = N&(-N);
22         int t = N+x;
23         return t | ((N^t)/x)>>2;
24     }
25 };

1 1 1 0 0 //1,2,3

1 1 0 1 0 //1,2,4

1 0 1 1 0 //1,3,4

0 1 1 1 0 //2,3,4

1 1 0 0 1 //1,2,5

1 0 1 0 1 //1,3,5

0 1 1 0 1 //2,3,5

1 0 0 1 1 //1,4,5

0 1 0 1 1 //2,4,5

0 0 1 1 1 //3,4,5

【版权声明】转载请注明出处：http://www.cnblogs.com/TenosDoIt/p/3461555.html

posted @ 2013-12-06 15:50  tenos  阅读(3596)  评论(0编辑  收藏  举报