解题思路:
- 模拟(双重循环):简单的遍历数组,第一重循环用于确定目的地,第二重循环用于判断长度,移动距离就是每个元素到目的地之间距离之和。很好算
- 看题解知可以用前一个盒子的操作数得到下一个盒子的操作数,先统计该盒子左边(包括自己)的1的个数和右边1的个数,每次向右移的时候左边的加一右边的减一即可,当然首先得把第一个的值给统计出来,同时在移动的过程中需要维护左边和右边的个数,即当移到一个有球的盒子时,计算完后,将左边加一,右边减一即可.
- 看到一个题解是这么弄的:只看1的盒子只要遇到1,则针对这个位置计算每一个盒子的操作数。当遍历完
boxes
中所有字符之后,再针对于每个盒子,执行操作数的sum
求和即可。缺点就是空间复杂度开销较大。
代码:
法一:
class Solution:
def minOperations(self, boxes: str) -> List[int]:
res = []
for i in range(len(boxes)):
s = sum(abs(j - i) for j, c in enumerate(boxes) if c == '1')
res.append(s)
return res
法二:
class Solution:
def minOperations(self, boxes: str) -> List[int]:
# left的初始值包括第一个,所以直接int即可
left, right, operations = int(boxes[0]), 0, 0
# 初始化right与operations
for i in range(1, len(boxes)):
if boxes[i] == '1':
right += 1
# 初始时距离就是下标,直接加上i即可
operations += i
# 将第一个答案填入
res = [operations]
# 开始遍历
for i in range(1, len(boxes)):
operations += left - right
# 维护left与right
if boxes[i] == '1':
left += 1
right -= 1
res.append(operations)
return res