前缀和与差分
前缀和与差分是算法设计中常用的技巧,用于高效处理数组区间操作问题。它们能够将复杂的区间操作转化为简单的单点操作,从而大幅提升算法的效率。本文将详细介绍前缀和与差分的概念、实现方法以及实际应用场景。
什么是前缀和?
前缀和(Prefix Sum)是指数组中从第一个元素到当前元素的所有元素之和。通过预处理数组,我们可以快速计算任意区间的和。
前缀和的构建
假设我们有一个数组 arr
,其前缀和数组 prefixSum
可以按以下方式构建:
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
和两个索引 l
和 r
,我们可以通过以下方式计算区间 [l, r]
的和:
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
可以按以下方式构建:
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
和两个索引 l
和 r
,以及一个值 val
,我们可以通过以下方式将区间 [l, r]
的所有元素增加 val
:
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]
。