LeetCode517_超级洗衣机(C++)

 1、初始分析:设最优的解法中,第i台洗衣机需要递的次数是itime。则最少移动次数为所有itime中的最大值。

举个简单的栗子整体感受一下
比如4台洗衣机瞭衣服数为3 4 4 4 5 则每一台洗衣机需要递的次数都是1。
具体操作为5给4一件,4给3一件,3给2一件,2给1一件。总共一次操作但分析后可以发现,这步操作可以简化为5给1一件。
这样我们就得出一个结论:分析一台洗衣机时,只需要分析它左边的总情况和右边的总情况,而不用管每一边内部具体的细节。


我们先设定几个参数。衣服总数sum     洗衣机总台数 n        平均值av             

左边缺少的衣服数 A = av * i - LeftSum,右边缺少的衣服数 B = av * ( n - 1 - i ) - RightSum。(如果多则为负值)


2、对于第i台洗衣机来说,总共有五种情况
①左右都缺,都需要从i号洗衣机递给她们,因为每次只能递一件,所以itime为A+B
②左右都多了,说明它们都得给i号洗衣机递,因为两边可以同时递,所以递的次数取决于需要调整次数多的那一边,即itime=MAX (-A,-B)
③左右都不缺也不多,这个很简单,i不用动,itime = 0
④一边的多一边少,但是多的量比少的量多,说明此时i里的衣服少了,多的那一个既需要给i,又需要给i的另一边。无论给谁,都得经过i,所以递的次数为多的量,即itime = MAX (|A|,|B/)
⑤一边的多一边少,但是少的量比多的量多,说明此时i里的衣服多了,少的那一边可以从i里取,也可以从多的那一边取。无论从哪取,都得经过i,所以递的次数为少的量,即itime =
MAX ( |Al,|B|) 。
④和⑤导致的结果一样,可以合为一种情况。
用这种方法求出所有的itime,最大值即为最少移动次数。

附上咱写的C++代码作参考。

#define MAX(A,B) ((A)>(B))?(A):(B)
int findMinMoves(vector<int>& machines)
{
    int sum = 0;
    for (int e : machines)
    {
        sum += e;
    }
    if (sum%machines.size())
        return -1;
    int av = sum / machines.size();
    int i = 0;
    int iLeftSum = 0;
    int iRightSum = sum - machines[i];
    int ret = 0;
    while (i < machines.size())
    {
        //左边需要增加的量A
        int LeftLack = i*av - iLeftSum;
        //右边需要增加的量B
        int RightLack = (machines.size() - 1 - i)*av - iRightSum;
        //5种情况:1.左右都缺,都需要从i号洗衣机递给她们 A+B
        //        2.左右都多,都需要送给i号洗衣机,可以同时给,所以经过i号洗衣机的次数是A和B的较大值
        //        3.左右都不缺,i号洗衣机ret=0;
        //        4.一边缺,一边多,i号洗衣机多。i需要递的次数为需求多的一边的量
        //		  5.一边缺,一边多,i号洗衣机少,i需要递的次数为需要多的一边的量。
        if (LeftLack > 0 && RightLack > 0)
        {
            ret = MAX(ret, machines[i] - av);
        }
        else if (LeftLack < 0 && RightLack < 0)
        {
            ret = MAX(ret, MAX(-LeftLack, -RightLack));
        }
        else if (LeftLack + RightLack == 0)
        {
            ret = MAX(ret, 0);
        }
        else
        {
            ret = MAX(ret, MAX(abs(LeftLack), abs(RightLack)));
        }
        iLeftSum += machines[i];
        ++i;
        if (i<machines.size())
            iRightSum -= machines[i];
    }
    return ret;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值