题干
有一个无序,元素个数为2N的正整数数组。要求:如何这个数组分割为元素个数为N的两个数组,并使两个子数组的和最接近。
我的解法
我的解法居然没有出现在书上和博客上,所以很让我怀疑我的解法有漏洞,但是又死活找不到。而且我的解法也可以应对原数组中有负数的情况。
如下图所示,将数组排序后:
- 最小的1和最大的20,给上面的一个子数组
- 次小的3和次大的17,给下面的数组
- 然后一直重复
- 剩下两个7和8的时候,一个给上面一个给下面
另外我还写了代码完成这个过程:
/**
* 编程之美 2.18题
* zy的解法,虽然结果正确,但是书上没有这样的解法,很不踏实,但是又找不出错
*/
#include <stdio.h>
#include <stdlib.h>
#define min(x,y) x<y?x:y
/**
* 测试用例
*/
int a1[]={1,5,7,8,9,6,3,11,20,17};
int a2[]={1,199,3,200};
int a3[]={0,0};
int a4[]={-5,-4,-3,-2,-1,1,2,3,4,5};
int *sub1;
int *sub2;
intcomp(const void *a,const void *b)
{
return*(int*)a-*(int*)b;
}
void get2subArray(int *a,int length){
int h;
int *i,*j;
int *p=a;
qsort(a,length,sizeof(int),intcomp);
printf("原数组:");
for(h=0;h<length;++h)
printf("%2d ",*p++);
int subLength=length/2;//这我们要求的子数组的长度,题设要求为原数组的一半
sub1=(int *)malloc((subLength)*sizeof(int));
sub2=(int *)malloc((subLength)*sizeof(int));
int *q1=sub1;
int *q2=sub2;
i=a;
j=a+length-1;
int flag=0; //标志:表明这一次数组的最大数和最小数给一个数组,下一轮给另一个数组
for( ; i<j; ++i,--j){//i<j不能去掉
if(*(