题意
一共nnn台洗衣机,每台洗衣机有a[i]a[i]a[i]台衣服,每次可以选择mmm台洗衣机向相邻的洗衣机传递一件衣服,问让所有洗衣机都有相同的衣服数量需要至少多少次操作?
题解
感觉这个题目还是比较难想的,还是看了别人的博客的才会做的
-
首先判断不可能的情况
-
我们考虑任意一台洗衣机i(从0开始计算),考虑为了让最后全部洗衣机都有相同的衣服,需要通过i传递的衣服有多少,我们计算在i左边的衣服总数前缀和prefixSum和右边的衣服总数后缀和suffixSum
假设最终结果每台洗衣机有avg件衣服,计算
{left=prefixSum−avg∗iright=suffixSum−avg∗(len−i−1) \begin{cases} left = prefixSum - avg*i \\ right = suffixSum - avg*(len - i - 1) \end{cases} {left=prefixSum−avg∗iright=suffixSum−avg∗(len−i−1)如果leftefteft为负数,表示需要通过iii(包括从iii)传递leftleftleft件衣服过来,如果leftleftleft为正数,表示需要通过传递leftleftleft件衣服到右边(包括第iii个位置). rightrightright同理
分以下三种情况讨论- 如果leftleftleft和rightrightright都大于0,表示两边都多衣服,因为可以同时操作,因为通过i传递的衣服为max(left,right)max(left, right)max(left,right)
- 如果leftleftleft和rightrightright都小于0,表示两边都少衣服,但是因此每次i只能传递一件衣服,因此答案为abs(left+right)abs(left+right)abs(left+right)
- 其余的情况是一个大于0一个小于0,其实和第一种类似,为max(abs(left),abs(right))max(abs(left), abs(right))max(abs(left),abs(right))
以上的方法我们可以计算出了为了到达最终状态,每个位置需要通过的衣服数,最后的答案应该是所有的数字中取最大值。
代码
public int findMinMoves(int[] machines) {
int sum = 0;
int len = machines.length;
for (int i = 0; i < len; i++) sum += machines[i];
if (sum % len != 0) return -1;
int avg = sum / len;
int prefixSum = 0;
int result = 0;
for (int i = 0; i < machines.length; i++) {
int suffixSum = sum - prefixSum - machines[i];
int left = prefixSum - avg * i;
int right = suffixSum - avg * (len - i - 1);
if (left >= 0 && right >= 0) result = Math.max(result, Math.max(left, right));
else if (left < 0 && right < 0) result = Math.max(result, -(left + right));
else result = Math.max(result, Math.max(result, Math.max(Math.abs(left), Math.abs(right))));
prefixSum += machines[i];
}
return result;
}

349

被折叠的 条评论
为什么被折叠?



