您的位置:首页 > 其它

Combinations

2015-07-10 22:09 218 查看
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个数的组合。

方法一:

将1~n,先由左到右固定一个,往后步长按照1往后计算,统计了k-1个数之后,将这k-1个数保留,找最后一个数的可能组合,最终找到k个数的子集加入到组合集中,下面固定第二个数,依上述步骤继续找k个数的子集。这相当于一个堆栈的形式,由栈底到栈顶,找最后一个数加入之后,依次出栈,再由栈底到栈顶。用递归可以实现。代码如下:
class Solution {
public:
vector<vector<int>> res;
vector<int> part;
void com(int dep,int maxdep,int n,int start)
{
if(dep==maxdep)
{
res.push_back(part);
return;
}
for(int i=start;i<=n;i++)
{
part[dep]=i;
com(dep+1,maxdep,n,i+1);
}
}
vector<vector<int>> combine(int n, int k) {
if(n<1) return res;
part.resize(k);
if(k==0||k==n)
{
part.resize(n);
for(int i=1;i<=n;i++)
part[i-1]=i;
res.push_back(part);
return res;
}
com(0,k,n,1);
return res;
}
};


递归示意图如下:

方法二:

递归的方法不容易理解,下面我给出自己的解题方法。求1~n中k个数组合的所有可能,我们可以生成一个n个位的数组,组成元素为0或者1.所有组成为:00...0~11...1.其中1代表1~n数组对应位是组合某子集的构成元素。所以我们只要找00...0~11...1中1出现k次的全部情况,也就找到所有的组合情况,代码如下:
class Solution {
public:
int int_to_bool(int n,vector<int>&index)//返回1出现的次数,也就是组合中元素的个数
{
int len=index.size();
index.clear();
index.resize(len);
int i=0;
int add=0;
while(n)
{
int temp=n%2;
index[i]=temp;
if(temp==1)
add++;
i++;
n/=2;
}
return add;
}
vector<vector<int>> combine(int n, int k) {
vector<vector<int>> res;
if(n<1) return res;
vector<int> num;
for(int i=1;i<=n;i++)
num.push_back(i);
if(k==0||k==n)
{
res.push_back(num);
return res;
}
vector<int> index(n,0);
for(int i=0;i<(1<<n);i++)
{
if(int_to_bool(i,index)==k)
{
vector<int> temp;
for(int j=0;j<n;j++)
{
if(index[j]==1)
temp.push_back(num[j]);
}
res.push_back(temp);
}
}
return res;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: