交换a,b中的元素,使|sum[a]-sum[b]|最小
转自:http://blog.csdn.net/beiyeqingteng/article/details/6958320
有两个序列a,b,大小都为n,序列元素的值任意整数,无序;
要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。
例如:
var a=[100,99,98,1,2, 3];
var b=[1, 2, 3, 4,5,40];(微软100题第32题)。
假设当前数组和的差为A:A = sum[a] - sum[b]
交换两个元素a[i],b[i],则差为
A' = sum[a] -a[i]+b[i] - (sum[b]-b[i]+a[i])
= sum[a]-sum[b]-2(a[i]-b[i])
= A-2x (设x = a[i]-b[i],)
假设A > 0, 当x 在 (0,A)之间时,做这样的交换才能使得交换后的a和b的和之差变小,x越接近A/2效果越好, 如果找不到在(0,A)之间的x,则当前的a和b就是答案。 所以算法大概如下:
在a和b中寻找使得x在(0,A)之间并且最接近A/2的i和j,交换相应的i和j元素,重新计算A后,重复前面的步骤直至找不到(0,A)之间的x为止。
代码如下:
1 #!/usr/bin/python 2 3 #a = [100, 99, 98, 1, 2, 3] 4 #b = [1, 2, 3, 4, 5, 40] 5 6 a = [100, 1, 2, 3] 7 b = [1, 2, 3, 96] 8 9 sum1 = sum(a) 10 sum2 = sum(b) 11 12 if sum1 > sum2: 13 big, small = a, b 14 else: 15 big, small = b, a 16 17 shift = True 18 while shift: 19 diff = abs(sum(big)-sum(small)) 20 maxdiff = diff #used to choose the best tempdiff 21 shift = False 22 for iv in big: 23 for jv in small: 24 tempdiff = abs(diff - 2*(iv-jv)) 25 if tempdiff < diff and tempdiff < maxdiff: 26 shift = True 27 maxdiff = tempdiff 28 pa = big.index(iv) 29 pb = small.index(jv) 30 if shift: 31 big[pa], small[pb] = small[pb], big[pa] 32 33 print a 34 print b