Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 23d9a24

Browse files
Merge pull request SharingSource#158 from SharingSource/ac_oier
✨feat: Add 517
2 parents 3f2ca0a + 05662bb commit 23d9a24

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed

‎Index/贪心算法.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
| [45. 跳跃游戏 II](https://leetcode-cn.com/problems/jump-game-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/jump-game-ii/solution/xiang-jie-dp-tan-xin-shuang-zhi-zhen-jie-roh4/) | 中等 | 🤩🤩🤩🤩 |
55
| [179. 最大数](https://leetcode-cn.com/problems/largest-number/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/largest-number/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-vn86e/) | 中等 | 🤩🤩🤩🤩 |
66
| [502. IPO](https://leetcode-cn.com/problems/ipo/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/ipo/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-fk1ra/) | 困难 | 🤩🤩🤩 |
7+
| [517. 超级洗衣机](https://leetcode-cn.com/problems/super-washing-machines/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/super-washing-machines/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-mzqia/) | 困难 | 🤩🤩🤩 |
78
| [524. 通过删除字母匹配到字典里最长单词](https://leetcode-cn.com/problems/longest-word-in-dictionary-through-deleting/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-word-in-dictionary-through-deleting/solution/gong-shui-san-xie-xiang-jie-pai-xu-shuan-qi20/) | 中等 | 🤩🤩🤩🤩 |
89
| [561. 数组拆分 I](https://leetcode-cn.com/problems/array-partition-i/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/array-partition-i/solution/jue-dui-neng-kan-dong-de-zheng-ming-fan-f7trz/) | 简单 | 🤩🤩🤩🤩 |
910
| [765. 情侣牵手](https://leetcode-cn.com/problems/couples-holding-hands/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/couples-holding-hands/solution/liang-chong-100-de-jie-fa-bing-cha-ji-ta-26a6/) | 困难 | 🤩🤩🤩 |
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[517. 超级洗衣机](https://leetcode-cn.com/problems/super-washing-machines/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-mzqia/)** ,难度为 **困难**
4+
5+
Tag : 「贪心算法」
6+
7+
假设有 `n` 台超级洗衣机放在同一排上。开始的时候,每台洗衣机内可能有一定量的衣服,也可能是空的。
8+
9+
在每一步操作中,你可以选择任意 `m` (`1 <= m <= n`) 台洗衣机,与此同时将每台洗衣机的一件衣服送到相邻的一台洗衣机。
10+
11+
给定一个整数数组 `machines` 代表从左至右每台洗衣机中的衣物数量,请给出能让所有洗衣机中剩下的衣物的数量相等的 最少的操作步数 。如果不能使每台洗衣机中衣物的数量相等,则返回 `-1`
12+
13+
示例 1:
14+
```
15+
输入:machines = [1,0,5]
16+
17+
输出:3
18+
19+
解释:
20+
第一步: 1 0 <-- 5 => 1 1 4
21+
第二步: 1 <-- 1 <-- 4 => 2 1 3
22+
第三步: 2 1 <-- 3 => 2 2 2
23+
```
24+
示例 2:
25+
```
26+
输入:machines = [0,3,0]
27+
28+
输出:2
29+
30+
解释:
31+
第一步: 0 <-- 3 0 => 1 2 0
32+
第二步: 1 2 --> 0 => 1 1 1
33+
```
34+
示例 3:
35+
```
36+
输入:machines = [0,2,0]
37+
38+
输出:-1
39+
40+
解释:
41+
不可能让所有三个洗衣机同时剩下相同数量的衣物。
42+
```
43+
44+
提示:
45+
* n == machines.length
46+
* 1 <= n <= 10ドル^4$
47+
* 0 <= machines[i] <= 10ドル^5$
48+
49+
---
50+
51+
### 基本分析
52+
53+
由于最终是要让所有洗衣机衣服相等,因此无解的情况很好分析,如果衣服数量 $sum$ 不能整除洗衣机数量 $n$ 的话,则返回 $-1,ドル否则必然有解(最坏情况下,每次只移动一件衣服,也可以使得衣服均分),要求最小移动次数。
54+
55+
由于每次操作都可以选任意台机器进行,不难猜想到最小移动次数为 **所有机器的「最小运输衣服数量」中的最大值**
56+
57+
计算某台洗衣机的「最小运输衣服数量」为经过当前机器的衣服数量(每次只能运输一件衣服),其值等于「起始左边衣服总量 与 最终左边衣服总量 的差值」+「起始右边衣服总量 与 最终右边衣服总量 的差值」,这里的差值都需要与 0ドル$ 取 $\max$ 代指缺少衣服的数量(因为如果是多余数量的话,可以通过同时传输来满足增加缺少的一边,减少多余的一边)。
58+
59+
我们猜想取所有机器中的「最小操作次数」的最大值即是答案。
60+
61+
**但这显然是理论的最小操作次数,我们来证明最终答案等于该值。**
62+
63+
假设理论最下操作次数为 $cnt,ドル真实答案为 $ans,ドル那么天然有 $ans \geq cnt,ドル我们需要通过证明 $ans \leq cnt$ 恒成立,来得证 $ans = cnt$。
64+
65+
可以通过「反证法」来证明 $ans \leq cnt$ 恒成立,假设 $ans > cnt,ドル即在某个特定序列中,实际最小操作次数 $ans$ 大于 $cnt,ドル假定我们是在位置 $x$ 中取得这个实际最小操作次数。
66+
67+
那么我们需要思考:**在没有无效传输的前提,什么情况下需要在 $x$ 位置传输大于 $cnt$ 件衣服来达到最终平衡。**
68+
69+
> 注:无效的意思是,衣服从位置 $x$ 的一边传到另外一边,随后又传输回来。
70+
71+
(注 1)当且仅当位置 $x$ 本身衣服为 0ドル$ 时,会发生该种情况。
72+
73+
也就是说首次传输,并没有实现「从 $x$ 左边往右边传输衣服」或者「从 $x$ 右边往左边传输衣服」的目的,而是需要先往位置 $x$ 填送衣服。
74+
75+
那么是否可能由起始衣服为 0ドル$ 的位置来取得 $ans$ 呢?我们通过「反证法」来证明「$ans$ 不可能由衣服为 0ドル$ 的起始位置得出」。
76+
77+
由于位置 $x$ 的起始数量为 0ドル,ドル那么位置 $x$ 必然至少有一侧的起始数量小于最终数量的(缺少衣服的),可以继续利用「反证法」来证明:
78+
79+
* 如果是两边都多于最终数量,说明最终是两边衣服流向位置 $x,ドル而且我们得到的 $ans$ 是两边的缺少总和,这种情况下得到的 $ans$ 为 0ドル,ドル但是整体衣服本身不相等,必然要消耗步数,必然不为 0ドル,ドル因此该情况不存在。
80+
81+
既然位置 $x$ 至少有一侧的起始数量小于最终数量的(缺少衣服的),那么自然我们可以将位置 $x$ 归到那一边,使得那一侧缺少衣服的数量更多,从而使答案 $ans$ 更大。这与 $ans$ 为所有位置中的「最小操作次数」最大的位置矛盾。
82+
83+
**得证,取得 $ans$ 的位置 $x$ 起始衣服必然不为 0ドル$。**
84+
85+
如果位置 $x$ 起始衣服必然不为 0ドル,ドル那么(注 1)的条件不成立,则 $ans > cnt$ 恒不成立,得证 $ans \leq cnt$ 恒成立。
86+
87+
**至此,我们通过三次「反证法」来证明了结论成立。首先通过「反证法」证明取得 $ans$ 的位置 $x$ 衣服不可能为 0ドル$;然后根据该位置起始衣服不为 0ドル$ 的前提条件,来证明 $ans > cnt$ 恒不成立,得证 $ans \leq cnt$ 恒成立,最终结合 $ans \geq cnt$ 来得证 $ans = cnt$。**
88+
89+
---
90+
91+
### 贪心
92+
93+
实现上,首先我们可以求得衣服总和 $sum$ 以及洗衣机数量 $n,ドル从而判断无解情况(`sum % n != 0`),或者计算最终每台洗衣机的衣服数量 $t = sum / n$。
94+
95+
然后使用两个变量 $ls$ 和 $rs$ 分别表示当前位置「左边的衣服总数」和「右边的衣服总数」,并在从左往右的遍历过程中实时维护。
96+
97+
对于某个位置 $x$ 而言,达到最终平衡需要从 $x$ 右边往左边运送的衣服数量为 $a = \max(i * t - ls, 0),ドル即左边的当前的衣服数量与最终状态的衣服数量的差值,与 0ドル$ 取 $\max$ 含义代表为如果当前左边衣服多于最终衣服数量时,此时不需要消耗从右到左的移动次数(只需要消耗从 $x$ 左边到 $x$ 右边的移动次数);右边分析同理,我们可以得到达到最终平衡需要从 $x$ 左边到右运送的衣服数量为 $b = \max((n - i - 1) * t - rs, 0)$。
98+
99+
在所有位置的 $a + b$ 之间取最大值即是答案。
100+
101+
代码:
102+
```Java
103+
class Solution {
104+
public int findMinMoves(int[] ms) {
105+
int n = ms.length;
106+
int sum = 0;
107+
for (int i : ms) sum += i;
108+
if (sum % n != 0) return -1;
109+
int t = sum / n;
110+
int ls = 0, rs = sum;
111+
int ans = 0;
112+
for (int i = 0; i < n; i++) {
113+
rs -= ms[i];
114+
int a = Math.max(t * i - ls, 0);
115+
int b = Math.max((n - i - 1) * t - rs, 0);
116+
ans = Math.max(ans, a + b);
117+
ls += ms[i];
118+
}
119+
return ans;
120+
}
121+
}
122+
```
123+
* 时间复杂度:$O(n)$
124+
* 空间复杂度:$O(1)$
125+
126+
---
127+
128+
### 最后
129+
130+
这是我们「刷穿 LeetCode」系列文章的第 `No.517` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
131+
132+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
133+
134+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
135+
136+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
137+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /