Leetcode 517

题意

一共 n n n台洗衣机,每台洗衣机有 a [ i ] a[i] a[i]台衣服,每次可以选择 m m m台洗衣机向相邻的洗衣机传递一件衣服,问让所有洗衣机都有相同的衣服数量需要至少多少次操作?

题解

感觉这个题目还是比较难想的,还是看了别人的博客的才会做的

  • 首先判断不可能的情况

  • 我们考虑任意一台洗衣机i(从0开始计算),考虑为了让最后全部洗衣机都有相同的衣服,需要通过i传递的衣服有多少,我们计算在i左边的衣服总数前缀和prefixSum和右边的衣服总数后缀和suffixSum

    假设最终结果每台洗衣机有avg件衣服,计算
    { l e f t = p r e f i x S u m − a v g ∗ i r i g h t = s u f f i x S u m − a v g ∗ ( l e n − i − 1 ) \begin{cases} left = prefixSum - avg*i \\ right = suffixSum - avg*(len - i - 1) \end{cases} {left=prefixSumavgiright=suffixSumavg(leni1)

    如果l e f t eft eft为负数,表示需要通过 i i i(包括从 i i i)传递 l e f t left left件衣服过来,如果 l e f t left left为正数,表示需要通过传递 l e f t left left件衣服到右边(包括第 i i i个位置). r i g h t right right同理
    分以下三种情况讨论

    1. 如果 l e f t left left r i g h t right right都大于0,表示两边都多衣服,因为可以同时操作,因为通过i传递的衣服为 m a x ( l e f t , r i g h t ) max(left, right) max(left,right)
    2. 如果 l e f t left left r i g h t right right都小于0,表示两边都少衣服,但是因此每次i只能传递一件衣服,因此答案为 a b s ( l e f t + r i g h t ) abs(left+right) abs(left+right)
    3. 其余的情况是一个大于0一个小于0,其实和第一种类似,为 m a x ( a b s ( l e f t ) , a b s ( r i g h t ) ) 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;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值