Leetcode 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
示例 2:
輸入: [0,3,0]
輸出: 2
解釋:
第一步: 0 <-- 3 0 => 1 2 0
第二步: 1 2 --> 0 => 1 1 1
示例 3:
輸入: [0,2,0]
輸出: -1
解釋:
不可能讓所有三個洗衣機同時剩下相同數量的衣物。
提示:
- n 的範圍是 [1, 10000]。
- 在每臺超級洗衣機中,衣物數量的範圍是 [0, 1e5]。
算法
(線性遍歷,答案分解) O(n)
由於每次操作每臺洗衣機只能選擇向左或者向右運送一件衣服,且多個洗衣機可以並行同時運送,故必定存在一個洗衣機,它運送的衣服數量等於答案。
我們可以枚舉每一臺洗衣機,計算經過它運送的衣服的數量。
首先如果衣服的總數量是洗衣機的整數倍,則必定存在一個解;否則返回 -1。
然後逐一枚舉洗衣機,假設當前枚舉的洗衣機編號為 i,則統計 left_sum = [0, i - 1] 中衣服的總數量和 right_sum = [i + 1, n - 1] 中衣服的總數量,若發現 left_sum < i * avg,即 i 左邊的衣服數量少,故需要經過這臺洗衣機從右向左運送的衣服數量為 r_2_l = i * avg - left_sum。從左向右運行的衣服數量 l_2_r 同理。
r_2_l + l_2_r 求和就是這臺洗衣機的工作量,對每一臺洗衣機都這樣求和得到工作量,取工作量最大的洗衣機就是答案。
#include<vector>
#include<algorithm>
using namespace std;
class Solution {
public:
int findMinMoves(vector<int>& machines) {
int n = machines.size(), ans = 0;
int tot = accumulate(machines.begin(), machines.end(), 0);
if (tot % n != 0) return -1;
int avg = tot / n;
int right_sum = tot, left_sum = 0;
for (int i = 0; i < n; i++) {
right_sum -= machines[i];
int r_2_l = max(i * avg - left_sum, 0);
int l_2_r = max((n - i - 1) * avg - right_sum, 0);
ans = max(ans, l_2_r + r_2_l);
left_sum += machines[i];
}
return ans;
}
};
Leetcode 517.超級洗衣機