1. 程式人生 > >Leetcode 517.超級洗衣機

Leetcode 517.超級洗衣機

machine solution blue 否則 同時 開始 操作 spa 輸出

超級洗衣機

假設有 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

解釋:

不可能讓所有三個洗衣機同時剩下相同數量的衣物。

提示:

  1. n 的範圍是 [1, 10000]。
  2. 在每臺超級洗衣機中,衣物數量的範圍是 [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.超級洗衣機