📜  门| GATE-CS-2016(套装1)|第 39 题(1)

📅  最后修改于: 2023-12-03 14:58:31.198000             🧑  作者: Mango

题目描述

给定一个长度为 $n$ 的数组 $arr$,$m,l,r$ 分别代表操作的次数,左右区间的端点。每次操作将区间 $[l,r]$ 内的数加 $m$。最后输出操作结束后数组 $arr$ 的内容。

函数签名
def update_array(arr, n, m, l, r):
    pass
输入
  • arr:长度为 $n$ 的数组,元素值在 $[-10^9, 10^9]$ 范围内。
  • n:整型变量,表示数组 arr 的长度,$1\leq n\leq 10^5$。
  • m:整型变量,表示每次操作将区间内的数加上的值,$-10^9\leq m\leq 10^9$。
  • l:整型变量,表示区间左端点的位置,$1\leq l\leq r\leq n$。
  • r:整型变量,表示区间右端点的位置,$1\leq l\leq r\leq n$。
输出
  • 无返回值,直接修改输入的数组。
示例
arr = [1, 2, 3, 4, 5]
update_array(arr, len(arr), 2, 2, 4)
assert arr == [1, 4, 5, 6, 5]
实现思路

本题考察的是数组的基本操作,即对一个区间内的数加上一个固定值。暴力做法可以循环该区间内的数,依次加上 $m$。时间复杂度为 $O(n)$。优化的做法可以在 $O(1)$ 的时间内完成。需要在数组 arr 上做一些预处理,做完后每次操作就可以在 $O(1)$ 的时间内完成。

预处理的思想就是用差分数组。差分数组 $d_i$ 表示 $arr_i - arr_{i-1}$ 的值。将操作应用在区间 $[l,r]$ 上,就是去修改数组 $d$ 的值。将 $d_l$ 加上 $m$,将 $d_{r+1}$ 减去 $m$。那么在对 $arr$ 数组求值时,只需要计算前缀和即可得到 $arr$ 数组。

代码片段
def update_array(arr, n, m, l, r):
    # 构建差分数组
    d = [0] * n
    d[l-1] += m
    if r < n:
        d[r] -= m
        
    # 求前缀和
    for i in range(1, n):
        d[i] += d[i-1]
    
    # 更新 arr
    for i in range(n):
        arr[i] += d[i]
复杂度分析
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(n)$