两个个数相同的数组,通过交换数组内容,实现数组之和之间的差值最小
这个思路比较简单:
- 对两个数组排序,计算数组和
- 计算当前差值
- 和较大的数组从前到后,较小的数组从后到前,比较数值的差值,如果差值的2倍小于数组和的差值就进行交换,直到数组和差值不再减小
//简单的插入排序 void sort_arr(int *arr, int size) { int tmp, i, j, k; for (i = 1; i < size; i++) { for (j = 0; j < i; j++) { if (arr[i] < arr[j]) { tmp = arr[i]; for (k = i; k > j; k--) { arr[k] = arr[k-1]; } arr[j] = tmp; } } } } //计算数组和 int sum_arr(int *arr, int size) { int sum = 0; int i; for (i = 0; i < size; i++) sum += arr[i]; return sum; } void min_devation(int *arr1, int *arr2, int size) { int sumA = sum_arr(arr1, size); int sumB = sum_arr(arr2, size); int sumMa = (sumA>sumB)?sumA:sumB; int sumMi = (sumA>sumB)?sumB:sumA; int *arrMx = (sumA>sumB)?arr1:arr2; int *arrMi = (sumA>sumB)?arr2:arr1; int mi, mx, i, j, tmp; int de = sumMa - sumMi; int de_tmp, ex; printf("0.sumMi = %d, sumMx = %d\n", sum_arr(arrMi, size), sum_arr(arrMx, size)); if (0 == de) return ; sort_arr(arrMx, size); sort_arr(arrMi, size); while (de) { de_tmp = de; mi = arrMi[0]; mx = arrMx[size-1]; ex = 2*(mx-mi); //交换后使得差值为0,直接交换并退出 if (ex == de) { tmp = mi; arrMi[0] = arrMx[size-1]; arrMx[size-1] = tmp; printf("1.sumMi = %d, sumMx = %d\n", sum_arr(arrMi, size), sum_arr(arrMx, size)); return; } //差值比数组和大,查找是否存在更小的差值 if (ex > de) { for (i = 0; i < size; i++) { for (j = size-1; j >= 0; j--) { tmp = 2*(arrMx[j] - arrMi[i]); //差值等于数组和差,直接交换返回 if (tmp == de) { tmp = arrMi[i]; arrMi[i] = arrMx[j]; arrMx[j] = tmp; printf("2.sumMi = %d, sumMx = %d\n", sum_arr(arrMi, size), sum_arr(arrMx, size)); return; } //负的差值不需要交换,只会增大数组和的差 if (tmp <= 0) { break; } if (tmp < de) { ex = arrMi[i]; arrMi[i] = arrMx[j]; arrMx[j] = ex; sort_arr(arrMi, size); sort_arr(arrMx, size); de -= tmp; } } } } else { tmp = mi; arrMi[0] = arrMx[size-1]; arrMx[size-1] = tmp; sort_arr(arrMi, size); sort_arr(arrMx, size); } de = sum_arr(arrMx, size) - sum_arr(arrMi, size); printf("de = %d, de_tmp = %d\n", de, de_tmp); if (de_tmp <= de) { break; } } printf("4.sumMi = %d, sumMx = %d\n", sum_arr(arrMi, size), sum_arr(arrMx, size)); return; }