数组操作次数计算 | 豆包MarsCode AI刷题

97 阅读3分钟

问题描述

小C得到了一个数组,他要对这个数组进行一些操作,直到数组为空。每次操作时,他会执行以下步骤:

  1. 如果数组的第一个元素 a[0] 等于0,则直接删除 a[0],并将数组中剩余的所有元素向左移动以填补空缺。
  2. 否则,将 a[0] 个 a[0]-1 添加到数组末尾,并将 a[0] 减少1。

小C想知道,在进行这些操作直到数组为空时,总共进行了多少次操作。结果需要对 109+7109+7 取模。

思路分析

  1. 操作定义

    • 如果数组的第一个元素 a[0] 等于0,删除 a[0]
    • 否则,将 a[0] 个 a[0]-1 添加到数组末尾,并将 a[0] 减少1。
  2. 操作次数计算

    • 每次操作,如果 a[0] 为0,操作次数加1。
    • 否则,将 a[0] 个 a[0]-1 添加到数组末尾,并将 a[0] 减少1。操作次数加1。(我认为操作次数应该增加 a[0]+1 次(因为每次添加 a[0] 个元素并减少 a[0] 的值))。
    • 所以无论操作是具体什么,每次判断a[0] 是否为0,操作次数都加1.
  3. 模拟过程

    • 使用队列(或列表)来模拟数组的操作。
    • 不断执行上述操作直到队列为空。
  4. 模运算

    • 返回最终结果操作次数时,对 10^9+7 取模。

实现步骤

  1. 初始化操作次数 total_operations 为0。

  2. 使用一个队列 q 来存储数组元素。

  3. 循环直到队列为空:

    • 如果队列的第一个元素为0,移除它。
    • 否则,将 q[0] 个 q[0] - 1 添加到队列末尾,并将 q[0] 减少1。
    • 操作次数 total_operations +1。
  4. 注意

    • 可以在每次增加操作次数时进行取模操作,以防止溢出。
    • 确保在 deque 为空时正确退出循环。

代码实现

MOD = 10 ** 9 + 7
def solution(n: int, a: list) -> int:
    from collections import deque
    q = deque(a)
    total_operations = 0

    while q:
        if q[0] == 0:
        q.popleft()
        else:
            count = q[0]
            q[0] -= 1
            new_elements = [q[0]] * count
            q.extend(new_elements)  # 将 count 个 q[0] 添加到 deque 末尾
        total_operations = total_operations + 1
    return total_operations % MOD


if __name__ == '__main__':
    print(solution(n = 3, a = [2, 3, 4]) == 257)
    print(solution(n = 5, a = [1, 1, 1, 1, 1]) == 15)
    print(solution(n = 4, a = [10, 5, 3, 7]) == 68658871)

数组末尾加元素可以用append: 每次当数组的第一个元素 q[0] 不为0时,我们会将 q[0] 个 q[0] - 1 添加到数组的末尾。这通过以下循环实现:

	for _ in range(count):

	    q.append(q[0])

然而,这个循环实际上是在做一件非常简单的事情:它只是将当前 q[0] 的值(在减少1之前)重复添加到队列的末尾 count 次。由于我们每次循环都会查看 q[0] 的当前值(它在每次迭代中都不会改变,直到外部循环的下一次迭代)。