算法练习笔记(十二)—— 超级洗衣机

https://leetcode.com/problems/super-washing-machines/#/description

You have n super washing machines on a line. Initially, each washing machine has some dresses or is empty.

For each move, you could choose any m (1 ≤ m ≤ n) washing machines, and pass one dress of each washing machine to one of its adjacent washing machines at the same time .

Given an integer array representing the number of dresses in each washing machine from left to right on the line, you should find theminimum number of moves to make all the washing machines have the same number of dresses. If it is not possible to do it, return -1.

Example1

Input: [1,0,5]

Output: 3

Explanation: 
1st move:    1     0 <-- 5    =>    1     1     4
2nd move:    1 <-- 1 <-- 4    =>    2     1     3    
3rd move:    2     1 <-- 3    =>    2     2     2   

Example2

Input: [0,3,0]

Output: 2

Explanation: 
1st move:    0 <-- 3     0    =>    1     2     0    
2nd move:    1     2 --> 0    =>    1     1     1     

Example3

Input: [0,2,0]

Output: -1

Explanation: 
It's impossible to make all the three washing machines have the same number of dresses. 

Note:

  1. The range of n is [1, 10000].
  2. The range of dresses number in a super washing machine is [0, 1e5].
假设有n台洗衣机,每个洗衣机里的衣服数量都非负(废话= =),现在要移动衣服使每台洗衣机中的衣服数量一样,每一次能够同时移动不同洗衣机的一件衣服,求使衣服移动的最小步数
解答思考:
在刚开始,原谅我没有看到同时这个词,于是悲剧就发生了,我得出了不同时的动态规划解答,然而与同时的要求不符
我是从最后开始往前遍历洗衣机,然后每一次,都使最后一个洗衣机里的衣服数通过最小步数移动变为所需数量,然后将这一个洗衣机扔出容器,进行下一步,有一点贪心算法的感觉
为了慰藉我努力的心灵,我还是要把自己的错误解答放上来
(若不同时)
class Solution {
public:
    int findMinMoves(vector& machines) {
        int size = machines.size();
        int count = 0;
        for(int i = 0; i < size; i++){
            count += machines[i];
        }
        if(count%size != 0)return -1;
        else
        return MinMoves(machines, count / size);
    }
    
    int MinMoves(vector& mac, int key){
        int move = 0;
        int size = mac.size();
        if(size == 1)return 0;
        if(mac[size - 1] == key);
        else if(mac[size - 1] > key){
            move = mac[size - 1] - key;
            mac[size - 2] += move;
        }
        else if(mac[size - 1] < key){
            int nums = key - mac[size - 1];
            for(int i = size - 2; i >= 0; i --){
                if(mac[i] > 0 && mac[i] < nums){
                    move += mac[i] * (size - 1 - i);
                    nums -= mac[i];
                    mac[i] = 0;
                }
                else if(mac[i] > 0 && mac[i] >= nums){
                    move += nums * (size - 1 - i);
                    mac[i] -= nums;
                    break;
                }
            }
        }
        mac.pop_back();
        return move + MinMoves(mac, key);
    }

};

然后说到正确解答,我参考了dalao的解答,而且只用了八行!
在这个解答中,主要便是对本次情景做出分析,并拟出一个平衡参量来解决了同时的问题,由于在每个洗衣机中,所缺数量的衣服和多出来的衣服,都是要被移动的,因此设置一个总体的平衡量,对每个洗衣机内需要被移动的衣服进行计数,同时通过加和解决可以同时移动两件衣服的问题,如下所示:

int findMinMoves(vector& machines) {
    int totalDresses = 0, size = machines.size();
    for (auto i = 0; i < size; ++i) totalDresses += machines[i];
    if (totalDresses % size != 0) return -1;
    
    auto targetDresses = totalDresses / size, totalMoves = 0, ballance = 0;
    for (auto i = 0; i < size; ++i) {
        ballance += machines[i] - targetDresses;
        totalMoves = max(totalMoves, max(machines[i] - targetDresses, abs(ballance)));
    }
    return totalMoves;
}



你可能感兴趣的:(话唠,笔记,代码)