LC 1769. 移动所有球到每个盒子所需的最小操作数
题目描述
这是 LeetCode 上的 1769. 移动所有球到每个盒子所需的最小操作数 ,难度为 中等。
有 n
个盒子。给你一个长度为 n
的二进制字符串 boxes
,其中 boxes[i]
的值为 '0'
表示第 i
个盒子是 空 的,而 boxes[i]
的值为 '1'
表示盒子里有 一个 小球。
在一步操作中,你可以将 一个 小球从某个盒子移动到一个与之相邻的盒子中。第 i
个盒子和第 j
个盒子相邻需满足 abs(i - j) == 1
。注意,操作执行后,某些盒子中可能会存在不止一个小球。
返回一个长度为 n
的数组 answer
,其中 answer[i]
是将所有小球移动到第 i
个盒子所需的 最小 操作数。
每个 answer[i]
都需要根据盒子的 初始状态 进行计算。
示例 1:1
2
3
4
5
6
7
8输入:boxes = "110"
输出:[1,1,3]
解释:每个盒子对应的最小操作数如下:
1) 第 1 个盒子:将一个小球从第 2 个盒子移动到第 1 个盒子,需要 1 步操作。
2) 第 2 个盒子:将一个小球从第 1 个盒子移动到第 2 个盒子,需要 1 步操作。
3) 第 3 个盒子:将一个小球从第 1 个盒子移动到第 3 个盒子,需要 2 步操作。将一个小球从第 2 个盒子移动到第 3 个盒子,需要 1 步操作。共计 3 步操作。
示例 2:1
2
3输入:boxes = "001011"
输出:[11,8,5,4,3,4]
提示:
- $n = boxes.length$
- $1 <= n <= 2000$
boxes[i]
为'0'
或'1'
模拟
预处理两个与 boxes
等长的数组 l
和 r
:$l[i]$ 和 $r[i]$ 分别代表「将 $[0, i]$ 的小球移动到位置 $i$」以及「将 $[i, n - 1]$ 的小球移动到位置 $i$」所需要的步数。
所求的答案数组 ans
与数组 l
和 r
的关系为:$ans[i] = l[i] + r[i]$。
预处理两数组是简单的:分别从两个方向遍历 boxes
,使用变量 cur
代表当前处理到的前缀/后缀的小球总个数,变量 step
代表将当前所有前缀/后缀小球移动到位置 $i$ 所需要的步数。
Java 代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class Solution {
public int[] minOperations(String boxes) {
int n = boxes.length();
int[] l = new int[n + 10], r = new int[n + 10];
for (int i = 0, cur = 0, step = 0; i < n; i++) {
step += cur; cur += boxes.charAt(i) - '0'; l[i] = step;
}
for (int i = n - 1, cur = 0, step = 0; i >= 0; i--) {
step += cur; cur += boxes.charAt(i) - '0'; r[i] = step;
}
int[] ans = new int[n];
for (int i = 0; i < n; i++) ans[i] = l[i] + r[i];
return ans;
}
}
TypeScript 代码:1
2
3
4
5
6
7
8
9
10
11
12
13function minOperations(boxes: string): number[] {
const n = boxes.length
const l = new Array<number>(n + 10).fill(0), r = new Array<number>(n + 10).fill(0)
for (let i = 0, cur = 0, step = 0; i < n; i++) {
step += cur; cur += boxes[i] == '1' ? 1 : 0; l[i] = step;
}
for (let i = n - 1, cur = 0, step = 0; i >= 0; i--) {
step += cur; cur += boxes[i] == '1' ? 1 : 0; r[i] = step;
}
const ans = new Array<number>(n).fill(0)
for (let i = 0; i < n; i++) ans[i] = l[i] + r[i]
return ans
}
Python 代码:1
2
3
4
5
6
7
8
9
10
11
12
13class Solution:
def minOperations(self, boxes: str) -> List[int]:
n = len(boxes)
l, r = [0] * n, [0] * n
step, cur = 0, 0
for i in range(n):
step, cur = step + cur, cur + 1 if boxes[i] == '1' else cur
l[i] = step
step, cur = 0, 0
for i in range(n - 1, -1, -1):
step, cur = step + cur, cur + 1 if boxes[i] == '1' else cur
r[i] = step
return [l[i] + r[i] for i in range(n)]
- 时间复杂度:$O(n)$
- 空间复杂度:$O(n)$
最后
这是我们「刷穿 LeetCode」系列文章的第 No.1769
篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!