1. 程式人生 > >[LeetCode] Super Washing Machines 超級洗衣機

[LeetCode] Super Washing Machines 超級洗衣機

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 the minimum 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].

這道題題給了我們一堆工藤新一,噢不,是滾筒洗衣機。我們有許多洗衣機,每個洗衣機裡的衣服數不同,每個洗衣機每次只允許向相鄰的洗衣機轉移一件衣服,問要多少次才能使所有洗衣機的衣服數相等。注意這裡的一次移動是說所有洗衣機都可以移動一件衣服到其相鄰的洗衣機。這道題的程式碼量其實不多,難點是在於解題思路,難的是對問題的等價轉換等。博主也沒有做出這道題,博主想到了要先驗證衣服總數是否能整除洗衣機的數量,然後計算出每個洗衣機最終應該放的衣服數,返回跟初始狀態衣服數之差的最大值,但這種解法是不對的,無法通過這個test case [0, 0, 11, 5],最終每個洗衣機會留4件衣服,我想的那方法會返回7,然後正確答案是8。想想也是,如果這麼是這麼簡單的思路,這題怎麼會標記為Hard呢,還是圖樣圖森破啊。這裡直接參照

大神Chidong的帖子來做,我們就用上面那個例子,有四個洗衣機,裝的衣服數為[0, 0, 11, 5],最終的狀態會變為[4, 4, 4, 4],那麼我們將二者做差,得到[-4, -4, 7, 1],這裡負數表示當前洗衣機還需要的衣服數,正數表示當前洗衣機多餘的衣服數。我們要做的是要將這個差值陣列每一項都變為0,對於第一個洗衣機來說,需要四件衣服可以從第二個洗衣機獲得,那麼就可以把-4移給二號洗衣機,那麼差值陣列變為[0, -8, 7, 1],此時二號洗衣機需要八件衣服,那麼至少需要移動8次。然後二號洗衣機把這八件衣服從三號洗衣機處獲得,那麼差值陣列變為[0, 0, -1, 1],此時三號洗衣機還缺1件,就從四號洗衣機處獲得,此時差值陣列成功變為了[0, 0, 0, 0],成功。那麼移動的最大次數就是差值陣列中出現的絕對值最大的數字,8次,參見程式碼如下:

class Solution {
public:
    int findMinMoves(vector<int>& machines) {
        int sum = accumulate(machines.begin(), machines.end(), 0);
        if (sum % machines.size() != 0) return -1;
        int res = 0, cnt = 0, avg = sum / machines.size();
        for (int m : machines) {
            cnt += m - avg;
            res = max(res, max(abs(cnt), m - avg));
        }
        return res;
    }
};

參考資料: