宝宝精刷题笔记 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. 第 1 个盒子:将一个小球从第 2 个盒子移动到第 1 个盒子,需要 1 步操作,第 3 个盒子没有小球,不需要操作。
  2. 第 2 个盒子:将一个小球从第 1 个盒子移动到第 2 个盒子,需要 1 步操作,第 3 个盒子没有小球,不需要操作。
  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
posted @ 2022-12-02 11:34  cleveresthuang  阅读(59)  评论(0)    收藏  举报