这道题给我们一个数组,我们可以向相邻的位置移动一个元素,只要移动不冲突。让我们求为了使数组平均,最少移动次数。
解答:
1 如果衣服总数除洗衣机总数,余数不为0,则洗衣机中的衣服数不可能平均。
2 计算前缀和数组sum[i]表示前i索引元素和。
3 为了得到最后的平均,计算每个位置需要移动的衣服数。
4 cl表示为了使索引i左边的平均,左边的还需要衣服数。cl = sum[i] - avg * i;
5 rl表示为了使索引i右边的平均,右边的还需要衣服数。avg * (n - i - 1) - (sum[n] - sum[i + 1])
7 如果cl > 0 && cr > 0,表示两边都需要衣服,但不能同时向两边移动衣服,所以i位置需要移动衣服数为 cl+cr
8 cl < 0 && cr < 0,表示两边衣服都多,需要向i位置移动,两边可以同时移动所以移动步数为 Math.max(-cl, -cr)
9 对于其中一个大于0,一个小于0,位置i和值小于0的可以同时移动,移动步数为Math.max(Math.abs(cl), Math.abs(cr))
10 找到每个位置需要移动个数后,遍历找最大值
public int findMinMoves(int[] machines) {
int n = machines.length;
int[] sum = new int[n + 1];
for (int i = 0; i < n; i++) {
sum[i + 1] = sum[i] + machines[i];
}
if (sum[n] % n != 0) return -1;
int max = 0;
int avg = sum[n] / n;
for (int i = 0; i < n; i++) {
int cl = avg * i - sum[i];
int cr = avg * (n - i - 1) - (sum[n] - sum[i + 1]);
if (cl > 0 && cr > 0) {
max = Math.max(max, cl + cr);
} else if (cl < 0 && cr < 0) {
max = Math.max(max, Math.max(-cl, -cr));
} else {
max = Math.max(max, Math.max(Math.abs(cl), Math.abs(cr)));
}
}
return max;
}