主题:“华为面试题!8分钟做出来”,我做的思路,大家帮看一下对不对,谢谢哈~!
qingeng_1052
[专家分:0] 发布于 2009-01-15 02:13:00
原题:有两个数组a,b,大小都为n,数组元素的值任意,无序;
要求:通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小
原帖http://bbs.misuland.com/bbsstaticweb/bbs_bbsforumannounce1221209363477_2.html
我的答案:
我能想出来怎么做,不过我打字慢,8分钟打不出来!嘿嘿!
前边和大家想的都一样,也是计算出数组a和b的差值c,然后除以2再取整。
之后,再做一个循环过程:
做一个由所有的a和b的元素差值生成的二维数组sub[i][j]。然后,遍历这个数组寻找和c差值最小的元素,交换数组a和b中的元素i和j。如果,sub[i][j]和c的差值小于或等于1,结束循环,否则,继续。
大家帮看看啊!谢谢了!有写代码快的,帮忙写出来验证一下,不胜感激啊 !
回复列表 (共24个回复)
11 楼
woshiyun [专家分:300] 发布于 2009-01-21 08:13:00
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//定义数组大小
#define SIZE 3
void InitArray(int* a, int* b, int size)
{
srand((unsigned)time(NULL));
for(int i=0;i<SIZE;i++) a[i] = rand()%20, b[i] = rand()%20;
}
void ShowArray(int* arr, int size)
{
for(int i=0;i<size;i++) printf("%d\t", arr[i]);
printf("\n");
}
int ChangeArray(int* a, int* b, int size, int diffsum)
{
int res=1, i, j;
for(i=0;i<size;i++)
for(j=0;j<size;j++)
if((a[i]-b[j]<diffsum)&&(a[i]-b[j]>0))
{
a[i]^=b[j]^=a[i]^=b[j];
diffsum -= 2*(b[j]-a[i]);
res = 0;
if(diffsum<=0) return res;
}
return res;
}
void main(void)
{
int a[SIZE], b[SIZE], SumOfA, SumOfB, EndFlag=0, i;
InitArray(a, b, SIZE);
printf("Init array is:\n");
ShowArray(a,SIZE), ShowArray(b,SIZE);
while(!EndFlag)
{
for(i=0,SumOfA=0,SumOfB=0;i<SIZE;i++) SumOfA+=a[i], SumOfB+=b[i];
EndFlag = (SumOfA>SumOfB)?ChangeArray(a, b, SIZE, SumOfA-SumOfB):ChangeArray(b, a, SIZE, SumOfB-SumOfA);
}
printf("\nChanged array is:\n");
ShowArray(a,SIZE), ShowArray(b,SIZE);
for(i=0,SumOfA=0,SumOfB=0;i<SIZE;i++) SumOfA+=a[i], SumOfB+=b[i];
printf("\nSum of A is: %d\nSum of B is: %d\n", SumOfA, SumOfB);
}
12 楼
woshiyun [专家分:300] 发布于 2009-01-21 08:16:00
[quote]假设数据为 1 2 3 3 4 5
那么只有以下几种分法:
1 2 3 | 3 4 5
1 2 4 | 3 3 5
1 2 5 | 3 3 4
1 3 3 | 2 4 5
1 3 4 | 2 3 5
1 3 5 | 2 3 4
1 4 5 | 2 3 3
[/quote]
怎么可以这么假设。。。。
那假设数据为1,2,3,4,5,。。。。。,99,100呢?
13 楼
woshiyun [专家分:300] 发布于 2009-01-21 08:29:00
#include <stdio.h>
void ShowArray(int* arr, int size)
{
for(int i=0;i<size;i++) printf("%d\t", arr[i]);
printf("\n");
}
int ChangeArray(int* a, int* b, int size, int diffsum)
{
int res=1, i, j;
for(i=0;i<size;i++)
for(j=0;j<size;j++)
if((a[i]-b[j]<diffsum)&&(a[i]-b[j]>0))
{
a[i]^=b[j]^=a[i]^=b[j];
diffsum -= 2*(b[j]-a[i]);
res = 0;
if(diffsum<=0) return res;
}
return res;
}
void main(void)
{
int a[] = {1, 2, 8, 5};
int b[] = {1, 2, 3, 3};
int i, SumOfA, SumOfB, EndFlag=0, SIZE=sizeof(a)/sizeof(a[0]);
while(!EndFlag)
{
for(i=0,SumOfA=0,SumOfB=0;i<SIZE;i++) SumOfA+=a[i], SumOfB+=b[i];
EndFlag = (SumOfA>SumOfB)?ChangeArray(a, b, SIZE, SumOfA-SumOfB):ChangeArray(b, a, SIZE, SumOfB-SumOfA);
}
ShowArray(a,SIZE), ShowArray(b,SIZE);
for(i=0,SumOfA=0,SumOfB=0;i<SIZE;i++) SumOfA+=a[i], SumOfB+=b[i];
printf("\nSum of A is: %d\nSum of B is: %d\ndifferent = %d\n", SumOfA, SumOfB, SumOfA-SumOfB);
}
14 楼
bruceteen [专家分:42660] 发布于 2009-01-21 10:24:00
re woshiyun:
我明白你的算法了
1. 将 a中的每一个数 和 b中的每一个数 比较,如果交换他俩可以使得差值变小,那么就交换;
2. 每次交换后就重新做第一步
3. 如果一次遍历中没发现可以交换的数,则说明已经是最优了。
15 楼
bruceteen [专家分:42660] 发布于 2009-01-21 12:10:00
会不会存在“交换每一个数都无法使得差值变小,但同时交换一组数据可以使得差值变小”的情况呢?
虽然我没有找到这样的事例,但我也没能证明这种情况不存在。
16 楼
nyra [专家分:4800] 发布于 2009-01-29 12:30:00
你们都没有读懂题,这是面试题,不是竞赛.
第一要求只是交换两个数组的值.
第二并没有要求出最优解.
此题只是考一下解决问题的能力和对数组程的能力.
而且考官基本没有时间读你的程序.
基本评分标准是循环次数,一次循环80分,两个循环60分.程序有错相应扣分.
能解释清楚算法和语句的目的相应加分.
一次循环算法是这样
sum_a = 0; sum_b = 0;
for_each i in 0, n
if (sum_a > sum_b) swap(a[i], b[i]);
sum_a += a[i]; sum_b += b[i];
end for_each
要知道只有半小时的时间做题,还有很多客观题.
17 楼
jels108710 [专家分:30] 发布于 2009-01-31 21:16:00
能问个问题么?
a[i]^=b[j]^=a[i]^=b[j];
这句什么意思?没看懂
不好意思啊
18 楼
zhaozhi8543@163.com [专家分:0] 发布于 2009-02-19 17:46:00
先分析题目:
1、首先,有两个数组,长度为n(很多数),值随即(不确定);
2、要求是寻找两个数组之间差值最小;
3、方法是由两个数组交换其中的元素,前提是交换的基础上进行的,而不是将两个数组中的元素完全打乱或者是重组。
个人意见:
1、先将两个数组分别求和sum1和sum2;
2、然后求出这两个数组和的差值(假设sum1>sum2,sum1-sum2=n1,n1=5);
3、然后比较数组,开始交换元素:
假设:
a 1 2 3 4 5
b 2 3 4 5 6
2 2 3 4 5
1 3 4 5 6
n1=n1-1*2=3
3 2 3 4 5
1 2 4 5 6
n1=n1-1*2=1
4、如果差值的范围在-c<0<c(c为一个所有数间的最小差值)时,比较完成,或者是最坏的情况,进行过最大的循环(以上面为例进行过25次比较(n方))。
19 楼
youshaofu [专家分:20] 发布于 2009-02-19 23:21:00
好贴,顶一个
20 楼
youshaofu [专家分:20] 发布于 2009-02-20 23:43:00
这个问题好像没有哪位大侠搞定啊。
把这个问题贴出来是希望大家一起来讨论,跟是否是面试题有什么关系,用多长时间搞定也没有关系。关键是大家来讨论搞这个问题。
我来回复