Difference Array | Range update query in O(1)

Last Updated : 05 May, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

You are given an integer array arr[] and a list of queries. Each query is represented as a list of integers where:

  • [1, l, r, x]: Adds x to all elements from arr[l] to arr[r] (inclusive).
  • [2]: Prints the current state of the array.

You need to perform the queries in order.

Examples : 

Input: arr[] = [10, 5, 20, 40], queries = [ [1, 0, 1, 10], [2], [1, 1, 3, 20], [1, 2, 2, 30], [2] ]
Output: 20 15 20 40
20 35 70 60

Explanation: [1, 0, 1, 10]: Adds 10 to arr[0] and arr[1].
Array becomes [20, 15, 20, 40].

  • (2): Prints the array: 20 15 20 40.
  • [1, 1, 3, 20)]: Adds 20 to arr[1], arr[2], and arr[3].
    Array becomes [20, 35, 40, 60].
  • [1, 2, 2, 30]: Adds 30 to arr[2].
    Array becomes [20, 35, 70, 60].
  • (2): Prints the array: 20 35 70 60.

[Naive Approach] Using loops for each queries - O(n * q) time and O(1) space

A simple solution is to do following : 

  1. update(l, r, x) : Run a loop from l to r and add x to all elements from arr[l] to arr[r]
  2. printArray() : Simply print arr[].
C++
#include <iostream>
#include <vector>
using namespace std;

void update(vector<int> &arr, int l, int r, int x)
{
    for (int i = l; i <= r; i++)
    {
        arr[i] += x;
    }
}

void printArray(const vector<int> &arr)
{
    for (int num : arr)
    {
        cout << num << " ";
    }
    cout << endl;
}

int main()
{
    vector<int> arr = {10, 5, 20, 40};

    vector<vector<int>> queries = {{1, 0, 1, 10}, {2}, {1, 1, 3, 20}, {1, 2, 2, 30}, {2}};

    for (const auto &query : queries)
    {
        if (query[0] == 1)
        {
            // update operation
            int l = query[1];
            int r = query[2];
            int x = query[3];
            update(arr, l, r, x);
        }
        else if (query[0] == 2)
        {
            // print operation
            printArray(arr);
        }
    }

    return 0;
}
Java
import java.util.Arrays;
import java.util.List;

public class GfG{
    public static void update(int[] arr, int l, int r,
                              int x)
    {
        for (int i = l; i <= r; i++) {
            arr[i] += x;
        }
    }

    public static void printArray(int[] arr)
    {
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }

    public static void main(String[] args)
    {
        int[] arr = { 10, 5, 20, 40 };

        int[][] queries = { { 1, 0, 1, 10 },
                            { 2 },
                            { 1, 1, 3, 20 },
                            { 1, 2, 2, 30 },
                            { 2 } };

        for (int[] query : queries) {
            if (query[0] == 1) {
                // update operation
                int l = query[1];
                int r = query[2];
                int x = query[3];
                update(arr, l, r, x);
            }
            else if (query[0] == 2) {
                // print operation
                printArray(arr);
            }
        }
    }
}
Python
def update(arr, l, r, x):
    for i in range(l, r + 1):
        arr[i] += x


def print_array(arr):
    print(' '.join(map(str, arr)))


if __name__ == '__main__':
    arr = [10, 5, 20, 40]

    queries = [[1, 0, 1, 10], [2], [1, 1, 3, 20], [1, 2, 2, 30], [2]]

    for query in queries:
        if query[0] == 1:
            # update operation
            l, r, x = query[1], query[2], query[3]
            update(arr, l, r, x)
        elif query[0] == 2:
            # print operation
            print_array(arr)
C#
using System;
using System.Collections.Generic;

class GfG{
    static void Update(int[] arr, int l, int r, int x)
    {
        for (int i = l; i <= r; i++) {
            arr[i] += x;
        }
    }

    static void PrintArray(int[] arr)
    {
        foreach(int num in arr)
        {
            Console.Write(num + " ");
        }
        Console.WriteLine();
    }

    static void Main()
    {
        int[] arr = new int[] { 10, 5, 20, 40 };

        List<List<int>> queries = new List<List<int>>{
            new List<int>{ 1, 0, 1, 10 },
            new List<int>{ 2 },
            new List<int>{ 1, 1, 3, 20 },
            new List<int>{ 1, 2, 2, 30 }, new List<int>{ 2 }
        };

        foreach(var query in queries)
        {
            if (query[0] == 1) {
                // update operation
                int l = query[1];
                int r = query[2];
                int x = query[3];
                Update(arr, l, r, x);
            }
            else if (query[0] == 2) {
                // print operation
                PrintArray(arr);
            }
        }
    }
}
JavaScript
function update(arr, l, r, x)
{
    for (let i = l; i <= r; i++) {
        arr[i] += x;
    }
}

function printArray(arr) { console.log(arr.join(" ")); }

const arr = [ 10, 5, 20, 40 ];

const queries = [
    [ 1, 0, 1, 10 ], [ 2 ], [ 1, 1, 3, 20 ],
    [ 1, 2, 2, 30 ], [ 2 ]
];

queries.forEach(query => {
    if (query[0] === 1) {
        // update operation
        const [_, l, r, x] = query;
        update(arr, l, r, x);
    }
    else if (query[0] === 2) {
        // print operation
        printArray(arr);
    }
});

Output
20 15 20 40 
20 35 70 60 

Time Complexity: O(n * q), O(n) for each queries
Space Complexity: O(1)

[Expected Approach] Using Difference Array

Difference array d[i] of a given array arr[i] is defined as d[i] = arr[i] - arr[i-1] (for 0 < i < n) and d[0] = arr[0] considering 0 based indexing. Difference array can be used to perform range update queries "l r x" where l is left index, r is right index and x is value to be added and after all queries you can return original array from it. Where update range operations can be performed in O(1) complexity.

  1. update(l, r, x) : Add x to d[l] and subtract it from d[r+1], i.e., we do d[l] += x, d[r+1] -= x
  2. printArray() : Do a[0] = d[0] and print it. For rest of the elements, do arr[i] = arr[i-1] + d[i] and print them.

Illustration: Let us understand this with an example arr = [2, 5, 7, 9, 6]. The difference array would be d = [2, 3, 2, 2, -3]. After an update say update(1, 3, 4), we add 4 to index 1 and subtract from index 4, the difference array would become d = [2, 7, 2, 2, -7]. Now to print array, we print 2, 2 + 7 = 9, 9 + 2 = 11, 11 + 2 = 13, 13 + (-7) = 6

C++
#include <iostream>
#include <vector>
using namespace std;

vector<int> initDiffArray(vector<int> &arr)
{
    int n = arr.size();

    // Initialize difference array with an extra element
    vector<int> d(n + 1, 0);

    d[0] = arr[0];
    for (int i = 1; i < n; i++)
    {
        d[i] = arr[i] - arr[i - 1];
    }
    return d;
}

void update(vector<int> &d, int l, int r, int x)
{
    d[l] += x;
    d[r + 1] -= x;
}

void printArray(vector<int> &arr, vector<int> &d)
{
    for (int i = 0; i < arr.size(); i++)
    {
        if (i == 0)
            arr[i] = d[i];
        else
            arr[i] = d[i] + arr[i - 1];

        cout << arr[i] << " ";
    }
    cout << endl;
}

int main()
{
    vector<int> arr{10, 5, 20, 40};

    vector<int> d = initDiffArray(arr);

    vector<vector<int>> queries = {{1, 0, 1, 10}, {2}, {1, 1, 3, 20}, {1, 2, 2, 30}, {2}};

    for (const auto &query : queries)
    {
        if (query[0] == 1)
        {
            // If it's an update query: update(l, r, x)
            int l = query[1];
            int r = query[2];
            int x = query[3];
            update(d, l, r, x);
        }
        else if (query[0] == 2)
        {
            // If it's a print query: printArray()
            printArray(arr, d);
        }
    }

    return 0;
}
Java
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;

public class GfG{
    public static int[] initDiffArray(int[] arr) {
        int n = arr.length;
        int[] d = new int[n + 1];
        d[0] = arr[0];
        for (int i = 1; i < n; i++) {
            d[i] = arr[i] - arr[i - 1];
        }
        return d;
    }

    public static void update(int[] d, int l, int r, int x) {
        d[l] += x;
        d[r + 1] -= x;
    }

    public static void printArray(int[] arr, int[] d) {
        for (int i = 0; i < arr.length; i++) {
            if (i == 0)
                arr[i] = d[i];
            else
                arr[i] = d[i] + arr[i - 1];
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] arr = {10, 5, 20, 40};
        int[] d = initDiffArray(arr);
        List<int[]> queries = new ArrayList<>();
        queries.add(new int[]{1, 0, 1, 10});
        queries.add(new int[]{2});
        queries.add(new int[]{1, 1, 3, 20});
        queries.add(new int[]{1, 2, 2, 30});
        queries.add(new int[]{2});

        for (int[] query : queries) {
            if (query[0] == 1) {
                // If it's an update query: update(l, r, x)
                int l = query[1];
                int r = query[2];
                int x = query[3];
                update(d, l, r, x);
            } else if (query[0] == 2) {
                // If it's a print query: printArray()
                printArray(arr, d);
            }
        }
    }
}
Python
def init_diff_array(arr):
    n = len(arr)
    d = [0] * (n + 1)
    d[0] = arr[0]
    for i in range(1, n):
        d[i] = arr[i] - arr[i - 1]
    return d


def update(d, l, r, x):
    d[l] += x
    d[r + 1] -= x


def print_array(arr, d):
    for i in range(len(arr)):
        if i == 0:
            arr[i] = d[i]
        else:
            arr[i] = d[i] + arr[i - 1]
        print(arr[i], end=' ')
    print()


if __name__ == '__main__':
    arr = [10, 5, 20, 40]
    d = init_diff_array(arr)
    queries = [[1, 0, 1, 10], [2], [1, 1, 3, 20], [1, 2, 2, 30], [2]]

    for query in queries:
        if query[0] == 1:
            # If it's an update query: update(l, r, x)
            l, r, x = query[1], query[2], query[3]
            update(d, l, r, x)
        elif query[0] == 2:
            # If it's a print query: print_array()
            print_array(arr, d)
C#
using System;
using System.Collections.Generic;

class GfG{
    static int[] InitDiffArray(int[] arr)
    {
        int n = arr.Length;
        int[] d = new int[n + 1];
        d[0] = arr[0];
        for (int i = 1; i < n; i++) {
            d[i] = arr[i] - arr[i - 1];
        }
        return d;
    }

    static void Update(int[] d, int l, int r, int x)
    {
        d[l] += x;
        d[r + 1] -= x;
    }

    static void PrintArray(int[] arr, int[] d)
    {
        for (int i = 0; i < arr.Length; i++) {
            if (i == 0)
                arr[i] = d[i];
            else
                arr[i] = d[i] + arr[i - 1];
            Console.Write(arr[i] + " ");
        }
        Console.WriteLine();
    }

    static void Main()
    {
        int[] arr = { 10, 5, 20, 40 };
        int[] d = InitDiffArray(arr);
        List<int[]> queries = new List<int[]>{
            new int[] { 1, 0, 1, 10 }, new int[] { 2 },
            new int[] { 1, 1, 3, 20 },
            new int[] { 1, 2, 2, 30 }, new int[] { 2 }
        };

        foreach(var query in queries)
        {
            if (query[0] == 1) {
                // If it's an update query: update(l, r, x)
                int l = query[1];
                int r = query[2];
                int x = query[3];
                Update(d, l, r, x);
            }
            else if (query[0] == 2) {
                // If it's a print query: printArray()
                PrintArray(arr, d);
            }
        }
    }
}
JavaScript
function initDiffArray(arr)
{
    const n = arr.length;
    const d = new Array(n + 1).fill(0);
    d[0] = arr[0];
    for (let i = 1; i < n; i++) {
        d[i] = arr[i] - arr[i - 1];
    }
    return d;
}

function update(d, l, r, x)
{
    d[l] += x;
    d[r + 1] -= x;
}

function printArray(arr, d)
{
    for (let i = 0; i < arr.length; i++) {
        if (i === 0)
            arr[i] = d[i];
        else
            arr[i] = d[i] + arr[i - 1];
        process.stdout.write(arr[i] + " ");
    }
    console.log();
}

const arr = [ 10, 5, 20, 40 ];
const d = initDiffArray(arr);
const queries = [
    [ 1, 0, 1, 10 ], [ 2 ], [ 1, 1, 3, 20 ],
    [ 1, 2, 2, 30 ], [ 2 ]
];

queries.forEach(query => {
    if (query[0] === 1) {
        // If it's an update query: update(l, r, x)
        const l = query[1];
        const r = query[2];
        const x = query[3];
        update(d, l, r, x);
    }
    else if (query[0] === 2) {
        // If it's a print query: printArray()
        printArray(arr, d);
    }
});

Output: 

20 15 20 40 
20 35 70 60 

Time complexity:
For update here is improved to O(1).
For printArray() still takes O(n) time. 
Auxiliary Space: O(n)


Next Article

Similar Reads