1、思路概述:
求一个数组中两部分的最小差值,即将一个数组分成两部分,这两部分要求差值最小。例如:
{1,2,3,5,7},那么在这个数组中,可以被分为{1,3,5}{2,7}两个数组使其差为0,是其差为最小。
由题目要求可见,我们还是要牵扯到求出问题的自己的过程,所以自然而然的就要涉及到回溯算法——子集树的问题。
2、代码实现:
static int[] brr;//辅助数组
static int[] best;//最佳值记录数组
static int min=Integer.MAX_VALUE;//最小差值
static int c;//未选择元素和
static int cv;//已选择元素和
public static void find(int[] arr,int i){
if(i==arr.length){
if(min>Math.abs(c-cv)){//当当前的最小值大于c-cv的绝对值的时候
min=Math.abs(c-cv);//更新最小值
for(int j=0;j<i;j++){
best[j]=brr[j];//最优解中记录当前选择
}
}
}else {
brr[i]=1;//已选择元素
c-=arr[i];//从未选择元素中减去已选数组
cv+=arr[i];//已选数组加上刚刚选择的数字
find(arr,i+1);
c+=arr[i];//从左子树回退,未选数字和加上刚刚回退的数字
cv-=arr[i];//已选数字和减去回退数字
brr[i]=0;
find(arr,i+1);
}
}
public static void main(String[] args) {
int [] array={1,2,3,5,7};
brr=new int[array.length];//定义辅助左右数组
best=new int[array.length];//最佳解数组
for (int i=0;i<array.length;i++){
c+=array[i];//先计算整个数组的和
}
find(array,0);
for(int i=0;i<array.length;i++){
if(best[i]==1){//将best中选中的数打印
System.out.println(array[i]+" ");
}
}
System.out.println();
}
}