Difference Array

Represent range updates compactly by storing changes between adjacent values.

Difference Array

A difference array stores how each element changes from the previous element. It lets you apply range additions in constant time and reconstruct the final array with a prefix sum.

You use it when many range updates are applied before the final values are needed.

Problem

Given an array $A$ of length $n$, support range updates of the form:

$$ A[i] = A[i] + x $$

for every index $i$ where:

$$ l \le i \le r $$

Structure

Define a difference array $D$ such that:

$$ D[0] = A[0] $$

and for $i > 0$:

$$ D[i] = A[i] - A[i - 1] $$

To add $x$ over range $[l, r]$:

  • add $x$ to $D[l]$
  • subtract $x$ from $D[r + 1]$ if $r + 1 < n$

Algorithm

Build the difference array:

build_difference(A):
    n = length(A)
    D[0] = A[0]
    for i from 1 to n - 1:
        D[i] = A[i] - A[i - 1]
    return D

Apply a range addition:

range_add(D, l, r, x):
    D[l] += x
    if r + 1 < length(D):
        D[r + 1] -= x

Reconstruct the array:

reconstruct(D):
    A[0] = D[0]
    for i from 1 to length(D) - 1:
        A[i] = A[i - 1] + D[i]
    return A

Example

Let

$$ A = [8, 3, 5, 1, 9] $$

The difference array is:

$$ D = [8, -5, 2, -4, 8] $$

Add $4$ to range $[1, 3]$:

$$ D[1] = -1 $$

and

$$ D[4] = 4 $$

So:

$$ D = [8, -1, 2, -4, 4] $$

Reconstruct:

index prefix sum value
0 8 8
1 7 7
2 9 9
3 5 5
4 9 9

Result:

$$ [8, 7, 9, 5, 9] $$

Correctness

The difference array records where value changes begin and end. Adding $x$ at $D[l]$ increases every reconstructed value from index $l$ onward. Subtracting $x$ at $D[r + 1]$ cancels that increase after index $r$. Therefore, only indices in $[l, r]$ receive the update.

Reconstruction by prefix sums restores the original values plus all encoded updates.

Complexity

operation time
build $O(n)$
range add $O(1)$
reconstruct $O(n)$

Space usage:

$$ O(n) $$

When to Use

Difference arrays are appropriate when:

  • many range updates are known before queries
  • final values are needed after all updates
  • updates are additive
  • the array can be reconstructed in one pass

They are less suitable when range queries must be answered between updates. In that case, use a Fenwick tree or segment tree.

Implementation

def build_difference(a):
    if not a:
        return []

    d = [0] * len(a)
    d[0] = a[0]

    for i in range(1, len(a)):
        d[i] = a[i] - a[i - 1]

    return d

def range_add(d, l, r, x):
    d[l] += x
    if r + 1 < len(d):
        d[r + 1] -= x

def reconstruct(d):
    if not d:
        return []

    a = [0] * len(d)
    a[0] = d[0]

    for i in range(1, len(d)):
        a[i] = a[i - 1] + d[i]

    return a
func BuildDifference(a []int) []int {
    if len(a) == 0 {
        return nil
    }

    d := make([]int, len(a))
    d[0] = a[0]

    for i := 1; i < len(a); i++ {
        d[i] = a[i] - a[i-1]
    }

    return d
}

func RangeAdd(d []int, l, r, x int) {
    d[l] += x
    if r+1 < len(d) {
        d[r+1] -= x
    }
}

func Reconstruct(d []int) []int {
    if len(d) == 0 {
        return nil
    }

    a := make([]int, len(d))
    a[0] = d[0]

    for i := 1; i < len(d); i++ {
        a[i] = a[i-1] + d[i]
    }

    return a
}