宝宝精刷题笔记 1769. 移动所有球到每个盒子所需的最小操作数
问题描述:
有 n 个盒子。给你一个长度为 n 的二进制字符串boxes,其中 boxes[i] 的值为'0'表示第 i 个盒子是空的,而 boxes[i] 的值为 '1' 表示盒子里有一个小球。
在一步操作中,你可以将一个小球从某个盒子移动到一个与之相邻的盒子中。第 i 个盒子和第 j 个盒子相邻需满足 abs(i - j) == 1 。注意,操作执行后,某些盒子中可能会存在不止一个小球。
返回一个长度为 n 的数组 answer ,其中 answer[i] 是将所有小球移动到第 i 个盒子所需的 最小 操作数。
示例1:
输入:boxes = "110"
输出:[1,1,3]
解释:每个盒子对应的最小操作数如下:
- 第 1 个盒子:将一个小球从第 2 个盒子移动到第 1 个盒子,需要 1 步操作,第 3 个盒子没有小球,不需要操作。
- 第 2 个盒子:将一个小球从第 1 个盒子移动到第 2 个盒子,需要 1 步操作,第 3 个盒子没有小球,不需要操作。
- 第 3 个盒子:将一个小球从第 1 个盒子移动到第 3 个盒子,需要 2 步操作。将一个小球从第 2 个盒子移动到第 3 个盒子,需要 1 步操作。共计 3 步操作。
示例2:
输入:boxes = "001011"
输出:[11,8,5,4,3,4]
解题思路
双重遍历
双层循环来解决该题。第一层循环表示盒子的位置,第二层循环用来计算将每个小球移动到该盒子的次数。
def minOperations1(boxes):
length = len(boxes)
answer = [0] * length
for i in range(length):
for j in range(length):
if j == i:
continue
if boxes[j] == '1':
answer[i] += abs(j - i)
return answer
双层循环来解决该题。第一层循环表示小球的位置,第二层循环用来计算将每个小球移动到该盒子的次数。由于不是每个位置上都有小球,因此将小球位置的循环放在最外层,可以降低循环的次数,从而减小时间复杂度
def minOperations2(boxes):
length = len(boxes)
answer = [0] * length
for i in range(length):
if boxes[i] == '1':
for j in range(length):
answer[j] += abs(i - j)
return answer
动态规划
第i+1个盒子所需的操作数可以看成是第i个盒子所需的操作数+boxes[0:i]的小球个数(0-i的小球再往右移动一次,从而落到i+1个盒子中)-boxesi:end的小球个数。
def minOperations2(boxes):
length = len(boxes)
answer = [0] * length
for i in range(length):
if boxes[i] == '1':
for j in range(length):
answer[j] += abs(i - j)
return answer