您的位置:首页 > 其它

给定一个数t,以及n个整数,在这n个数中找到加和为t的所有组合

2013-10-03 21:27 851 查看
【题目】给定一个数t,以及n个整数,在这n个数中找到加和为t的所有组合,例如t
= 4, n = 6,这6个数为 [4,
3, 2, 2, 1, 1],这样输出就有4个不同的组合它们的加和为4:
4, 3+1, 2+2, and 2+1+1. 请设计一个高效算法实现这个需求。-----阿里2011实习生笔试题

之前只是看了一下网上这个题的写法没自己动手写,以下为自己所写的程序。

注:此题可与创新工厂的那个题目(/article/7588310.html)对比着看一下,两者有点不同:本题数组中数字是有限的,而创新工场的那个题目每一个数字有无限个。

int partition(int *a,int low,int high)
{
int pivotKey=a[low];
while(low<high)
{
while (low<high && pivotKey<=a[high])
high--;
swap(a[low],a[high]);

while(low<high && pivotKey>=a[low])
low++;
swap(a[low],a[high]);
}
return low;
}

void QSort(int *a,int low,int high)
{
if (low<high)
{
int pivot=partition(a,low,high);
QSort(a,low,pivot);
QSort(a,pivot+1,high);
}
}

void QucikSort(int *a,int n)//自己写的快排
{
QSort(a,0,n-1);
}

void PrintCombination(int *a,int n,int sum,vector<int>& vec)
{	//a为输入数组,n为数组长度,sum为待查找的和,vec用于保存查找到的组合
if (sum==0)
{
vector<int>::iterator iter=vec.begin();
for (;iter!=vec.end();iter++)
{
cout<<*iter<<" ";
}
cout<<endl;
return;
}
else if(sum<0 || n<=0)
return;
vec.push_back(a[0]);//a[0]即*a,注指针a是变化的,每次指向后一个
PrintCombination(a+1,n-1,sum-a[0],vec);
vec.pop_back();

while(*a == *(a+1) && a < a+n) //【重要】跳过重复的数字
a++;
PrintCombination(a+1,n-1,sum,vec);
}

void main()
{
int a[8]={8,3,6,5,7,2,4,1};
cout<<"原来的数组:";
PrintArray(a,8);
QucikSort(a,8);
cout<<"排序后数组:";
PrintArray(a,8);
cout<<"-----------------------------"<<endl;
vector<int> vec;
int sum=10;
cout<<"和为"<<sum<<"的组合如下:"<<endl;
PrintCombination(a,8,sum,vec);
}


【注】:感觉对数组“排序”的作用就是为了跳过重复的数字,如果没有重复数字,完全不需要对数组进行排序。

测试1:(排序情况)



测试2:(不排序情况,前提是无重复数字)



测试3:(不跳过重复数字)



测试4:(跳过重复数字)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐