java编程:两个无序数组a和b,交换a,b中的元素,使得[序列a元素的和]与[序列b元素的和]之间的差最小。


题目:对于两个无序数组a和b,交换a,b中的元素,使得[序列a元素的和]与[序列b元素的和]之间的差最小。

 求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。  
    例如:  
     int[] a = {3,5,-10};  
      int[] b = {20, 25, 50}; 

  思路:  
     当前数组a和数组b的和之差为 A = sum(a) - sum(b) a的第i个元素和b的第j个元素交换后, 
     a和b的和之差为 A'  
      =sum(a) - a[i] + b[j] - (sum(b) - b[j] + a[i])  
     = sum(a) - sum(b) - 2 (a[i] -b[j])  
     = A - 2 (a[i] - b[j])  
      设x = a[i] - b[j], 则交换后差值变为 A’ = A - 2x 
  假设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为止。
 

备注:网上笔试题,代码是参考网上别人的,具体出处找不到了,请谅解。摘抄记录下来方便日后学习。如果有问题尽请批评指正,希望可以和大神一起交流。

java代码如下:

import java.util.Scanner;
public class MinSumASumB {  
    public static void main(String[] args) {  
        MinSumASumB minSumASumB=new MinSumASumB();  
//输入数组a
        Scanner s=new Scanner(System.in);
        int an=s.nextInt();
        int[] a=new int[1000];
        for(int i=0;i<an;i++){
            int next=s.nextInt();
            a[i]=next;
          }
//输入数组b
        int bn=s.nextInt();
        int[] b=new int[1000];
        for(int i=0;i<bn;i++){
            int next=s.nextInt();
            b[i]=next;
          }
        minSumASumB.swapToMinusDiff(a, b);  
       //输出交换后的a,b数组
        //System.out.println(Arrays.toString(a));  
       // System.out.println(Arrays.toString(b));  
    }  
  
    public void swapToMinusDiff(int[] a,int[] b){  
          
        int sumA=sum(a);  
        int sumB=sum(b);  
          
        if(sumA==sumB)return;  
          
        if(sumA<sumB){  
            int[] temp=a;  
            a=b;  
            b=temp;  
        }  
        int curDiff=1;  
        int oldDiff=Integer.MAX_VALUE;  
        int pA=-1;  
        int pB=-1;  
        boolean shift=true;  
        int len=a.length;//the length of a and b should be the same  
        while(shift&&curDiff>0){  
            shift=false;  
            curDiff=sum(a)-sum(b);  
            for(int i=0;i<len;i++){  
                for(int j=0;j<len;j++){  
                    int temp=a[i]-b[j];  
                    int newDiff=Math.abs(curDiff-2*temp);  
                    if(newDiff<curDiff&&newDiff<oldDiff){  
                        shift=true;  
                        oldDiff=newDiff;  
                        pA=i;  
                        pB=j;  
                    }  
                }  
            }  
            if(shift){  
                int temp=a[pA];  
                a[pA]=b[pB];  
                b[pB]=temp;  
            }  
        }  
        System.out.println("the min diff is "+oldDiff);  
    }  
    public int sum(int[] a){  
        int sum=0;  
        for(int each:a){  
            sum+=each;  
        }  
        return sum;  
    }  
}  


运行结果:

3
3 5 -10
3
20 25 50
the min diff is 3



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值