跳到主要内容

前缀和与差分

前缀和与差分是算法设计中常用的技巧,用于高效处理数组区间操作问题。它们能够将复杂的区间操作转化为简单的单点操作,从而大幅提升算法的效率。本文将详细介绍前缀和与差分的概念、实现方法以及实际应用场景。

什么是前缀和?

前缀和(Prefix Sum)是指数组中从第一个元素到当前元素的所有元素之和。通过预处理数组,我们可以快速计算任意区间的和。

前缀和的构建

假设我们有一个数组 arr,其前缀和数组 prefixSum 可以按以下方式构建:

python
def build_prefix_sum(arr):
n = len(arr)
prefixSum = [0] * n
prefixSum[0] = arr[0]
for i in range(1, n):
prefixSum[i] = prefixSum[i - 1] + arr[i]
return prefixSum

前缀和的应用

前缀和的主要应用是快速计算任意区间的和。例如,给定数组 arr 和两个索引 lr,我们可以通过以下方式计算区间 [l, r] 的和:

python
def range_sum(prefixSum, l, r):
if l == 0:
return prefixSum[r]
else:
return prefixSum[r] - prefixSum[l - 1]

示例

假设我们有一个数组 arr = [1, 2, 3, 4, 5],其前缀和数组为 prefixSum = [1, 3, 6, 10, 15]。如果我们想计算区间 [1, 3] 的和,可以使用 range_sum(prefixSum, 1, 3),结果为 9

什么是差分?

差分(Difference)是前缀和的逆操作,用于处理区间更新问题。差分数组 diff 的每个元素表示原数组 arr 中相邻元素的差值。

差分的构建

假设我们有一个数组 arr,其差分数组 diff 可以按以下方式构建:

python
def build_diff(arr):
n = len(arr)
diff = [0] * n
diff[0] = arr[0]
for i in range(1, n):
diff[i] = arr[i] - arr[i - 1]
return diff

差分的应用

差分的主要应用是快速进行区间更新。例如,给定数组 arr 和两个索引 lr,以及一个值 val,我们可以通过以下方式将区间 [l, r] 的所有元素增加 val

python
def range_update(diff, l, r, val):
diff[l] += val
if r + 1 < len(diff):
diff[r + 1] -= val

示例

假设我们有一个数组 arr = [1, 2, 3, 4, 5],其差分数组为 diff = [1, 1, 1, 1, 1]。如果我们想将区间 [1, 3] 的所有元素增加 2,可以使用 range_update(diff, 1, 3, 2),更新后的差分数组为 diff = [1, 3, 1, 1, -1]。通过差分数组,我们可以还原出更新后的原数组 arr = [1, 4, 5, 6, 5]

实际应用场景

前缀和的应用场景

前缀和常用于解决以下问题:

  1. 区间求和:快速计算数组中任意区间的和。
  2. 子数组问题:例如,找到和为特定值的子数组。
  3. 二维前缀和:扩展到二维数组,用于计算矩形区域的和。

差分的应用场景

差分常用于解决以下问题:

  1. 区间更新:快速对数组中的某个区间进行批量更新。
  2. 区间查询:结合前缀和,可以高效处理区间更新和查询问题。
  3. 二维差分:扩展到二维数组,用于处理矩形区域的更新。

总结

前缀和与差分是算法设计中非常实用的技巧,能够大幅提升处理数组区间操作的效率。通过预处理数组,我们可以将复杂的区间操作转化为简单的单点操作,从而简化问题的解决过程。

提示

练习:尝试实现一个二维前缀和和二维差分的算法,并解决一个相关的实际问题。