有两个序列 a,b,大小都为 n,序列元素的值任意整数,无序;
要求:通过交换 a,b 中的元素,使[序列 a 元素的和]与[序列 b 元素的和]之间的差最小。
例如:
var a=[100,99,98,1,2,3];var b=[1,2,3,4,5,40];
思路:
假设序列a和b的和分别为sumA和sumB,假设sumA>sumB。
交换a中的x和b中的y,交换之后得到的差为:
sumA-x+y-(sumB-y+x) = sumA-sumB-2(x-y)
如果要求差最小,那么abs(sumA-sumB-2(x-y))要最小,也就是x-y要更接近于0.5*(sumA-sumB)
如果一次遍历之后数组没有交换,说明当前交换任何一组数据都会使差增大,循环终止
public class Q32_Notice {
public static int Sum(int[] a)
{
int sum = 0;
for(int i = 0;i<a.length;i++)
sum += a[i];
return sum;
}
public static void getMinDiffer(int[] a,int[] b)
{
int[] big = {};
int[] small = {};
int differ = 0,min;
int i,j,suma,sumb;
int flag = 1;
while(flag == 1)
{
flag = 0;
int ai = 0;
int bj = 0;
suma = Sum(a);
sumb = Sum(b);
if(suma == sumb)
break;
else if(suma > sumb)
{
big = a;
small = b;
differ = suma - sumb;
}
else if(suma < sumb)
{
big = b;
small = a;
differ = sumb - suma;
}
min = differ;
for(i = 0;i< big.length;i++)
for(j = 0;j<small.length;j++)
{
int temp = big[i] - small[j];
if(Math.abs(differ-2*temp)<min)
{
min = Math.abs(differ-2*temp);
flag = 1;
ai = i;
bj = j;
}
}
if(flag == 1)
{
int mid = big[ai];
big[ai] = small[bj];
small[bj] = mid;
}
}
}
public static void main(String[] args) {
int[] a = {100,99,98,1,2,3};
int[] b = {1,2,3,4,5,40};
getMinDiffer(a, b);
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
System.out.println(Sum(a)-Sum(b));
}
}