517. 超级洗衣机

517. 超级洗衣机

题目

假设有 n 台超级洗衣机放在同一排上。开始的时候,每台洗衣机内可能有一定量的衣服,也可能是空的。

在每一步操作中,你可以选择任意 m (1 ≤ m ≤ n) 台洗衣机,与此同时将每台洗衣机的一件衣服送到相邻的一台洗衣机。

给定一个非负整数数组代表从左至右每台洗衣机中的衣物数量,请给出能让所有洗衣机中剩下的衣物的数量相等的最少的操作步数。如果不能使每台洗衣机中衣物的数量相等,则返回 -1。
示例 1:

输入: [1,0,5]

输出: 3

解释:
第一步: 1 0 <-- 5 => 1 1 4
第二步: 1 <-- 1 <-- 4 => 2 1 3
第三步: 2 1 <-- 3 => 2 2 2

思路

首先,计算所有机器上的任务数量总和sum,如果sum%n结果不为0,说明是无解的。如果有解,那么最终,每个机器上的任务数应该是sum/n,记为avg。
遍历所有的机器,每一个机器i,都要考虑以下的情况。设i之前的所有机器是L,i之后的所有机器是R,L和R都是不包括i的。那么,这里S_L表示L上所有任务的总和,S_R表示R上所有任务的总和。那么S_L-avg*l(l表示L上的机器数量)就是L这个整体需要向外发送或者接收的任务数量。对于S_R,同理。对于机器i,i-avg就是机器i所需要向外发送或者接收的任务数量。
例如,S_L=30,i-avg=10,S_R=-40,那么L和机器i就总共需要向R传40个任务,至少需要40轮才能发送完。
这里就出现了四种情况。
1、S_L>0 and S_R>0 :
这时候,i-avg必然是小于0的,说明L和R都需要向i发送多余的任务,那么轮数就是max(S_L,S_R)
2、S_L<0 and S_R<0:
这时候,i-avg必须是大于0的,说明i需要向L和R发送,但是i每次只能发一个,所以轮数就是i-avg
3、S_L< 0 and S_R > 0:
这时候,不需要管i-avg的值了,最大绝对值的那个就是轮数,而这个最大绝对值,必然出现在S_L和S_R中,否则就矛盾了。轮数就是max(abs(S_L),abs(S_R))
4、S_L>0 and S_R < 0:
和3同理,轮数就是max(abs(S_L),abs(S_R))

综上,可以将四种情况合并,得到两种:
1、S_L<0 and S_R<0:
轮数就是i-avg
2、其余情况
轮数就是max(abs(S_L),abs(S_R))

遍历所有的i,找到最大的轮数,就是最终的结果。
至于算法的正确性,不会证,应该和最大网络流什么的相关,就算了吧

代码

    public int findMinMoves(int[] machines) {
        int n = machines.length;
        int sum = 0;
        for(int i:machines){
            sum = sum+i;
        }
        if(sum%n!=0){
            return -1;
        }

        int avg = sum/n;
        int ans = 0;
        int left_sum = 0;
        for(int i=0;i<n;i++){
            int left_rest = left_sum - i*avg;
            int right_rest = (sum - left_sum -machines[i]) - (n-i-1)*avg;

            if(left_rest<0 && right_rest<0){
                ans = Math.max(ans,Math.abs(left_rest)+Math.abs(right_rest));
            }else{
                ans = Math.max(ans,Math.max(Math.abs(left_rest),Math.abs(right_rest)));
            }
            left_sum  = left_sum + machines[i];

        }
        return ans;
    }

补充

这题比较难,感觉思路拓展性有限,可能只适合这个题。另外标签有动态规划,但是没看出来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值