Open In App

Difference Array | Range update query in O(1)

Last Updated : 05 Jul, 2025
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

Given an array arr[] and a 2D array opr[][], where each row represents an operation in the form [l, r, v]. For each operation, add v to all elements from index l to r in arr. Return the updated array after applying all operations.

Examples : 

Input: arr[] = [2, 3, 5, 6, 7], opr[][] = [[2, 4, 2], [3, 4, -1]]
Output: [2, 3, 7, 7, 8]
Explanation: Operation [2, 4, 2]: Add 2 to elements at indices 2 to 4.
Updated array: [2, 3, 7, 8, 9]
Operation [3, 4, -1]: Subtract 1 from elements at indices 3 to 4.
Final array: [2, 3, 7, 7, 8]

Input: arr[] = [4, 5, 7, 9], opr[][] = [[1, 3, 1], [2, 3, -2]]
Ouput: [4, 6, 6, 8]
Explanation: After performing all the operations the final array look like [4, 6, 6, 8]

[Naive Approach] Using loops for each queries

For every operation (l, r, x), iterate from index l to r and add x to each element in that range. After all operations have been applied, traverse the array once to print the final result.

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

// Function to apply a single operation: 
// add x to elements from index l to r
void update(vector<int> &arr, int l, int r, int x) {
    for (int i = l; i <= r; i++) {
        arr[i] += x;
    }
}

// Function to apply all operations in order
vector<int> diffArray(vector<int>& arr,
                vector<vector<int>>& opr) {
    
    // Apply each operation [l, r, v] to the array
    // Here l , r are in 0 based indexing 
    for (auto &v : opr) {
        update(arr, v[0], v[1], v[2]);
    }
    return arr;
}

int main() {
   
    vector<int> arr = {2, 3, 5, 6, 7};
    vector<vector<int>> opr = {
        {2, 4, 2},   
        {3, 4, -1}   
    };

    vector<int> res = diffArray(arr, opr);

    for (int num : arr) {
        cout << num << " ";
    }
    cout << endl;

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

class GfG {

    // Function to apply a single operation: 
    // add x to elements from index l to r
    static void update(int[] arr, int l, int r, int x) {
        for (int i = l; i <= r; i++) {
            arr[i] += x;
        }
    }

    // Function to apply all operations in order
    static ArrayList<Integer> diffArray(int[] arr, int[][] opr) {
        for (int[] op : opr) {
            update(arr, op[0], op[1], op[2]);
        }

        ArrayList<Integer> result = new ArrayList<>();
        for (int num : arr) {
            result.add(num);
        }
        return result;
    }

    public static void main(String[] args) {
        int[] arr = {2, 3, 5, 6, 7};
        int[][] opr = {
            {2, 4, 2},
            {3, 4, -1}
        };

        ArrayList<Integer> res = diffArray(arr, opr);
        for (int num : res) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}
Python
# Function to apply a single operation: 
# add x to elements from index l to r
def update(arr, l, r, x):
    for i in range(l, r + 1):
        arr[i] += x

# Function to apply all operations in order
def diffArray(arr, opr):
    
    # Apply each operation [l, r, v] to the array
    # Here l , r are in 0 based indexing 
    for v in opr:
        update(arr, v[0], v[1], v[2])
    
    return arr


if __name__ == "__main__":
    
    arr = [2, 3, 5, 6, 7]
    opr = [
        [2, 4, 2],
        [3, 4, -1]
    ]

    res = diffArray(arr, opr)
    for num in arr:
        print(num, end=' ')
    print()
C#
using System;
using System.Collections.Generic;

class GfG {

    // Function to apply a single operation: 
    // add x to elements from index l to r
    static void update(int[] arr, int l, int r, int x) {
        for (int i = l; i <= r; i++) {
            arr[i] += x;
        }
    }

    // Function to apply all operations and return List<int>
    static List<int> diffArray(int[] arr, int[][] opr) {
        foreach (int[] op in opr) {
            update(arr, op[0], op[1], op[2]);
        }

        List<int> result = new List<int>(arr);
        return result;
    }

    static void Main() {
        int[] arr = {2, 3, 5, 6, 7};
        int[][] opr = {
            new int[] {2, 4, 2},
            new int[] {3, 4, -1}
        };

        List<int> res = diffArray(arr, opr);
        foreach (int num in res) {
            Console.Write(num + " ");
        }
        Console.WriteLine();
    }
}
JavaScript
// Function to apply a single operation: 
// add x to elements from index l to r
function update(arr, l, r, x) {
    for (let i = l; i <= r; i++) {
        arr[i] += x;
    }
}

// Function to apply all operations in order
function diffArray(arr, opr) {
    
    // Apply each operation [l, r, v] to the array
    // Here l , r are in 0 based indexing 
    for (let v of opr) {
        update(arr, v[0], v[1], v[2]);
    }
    
    return arr;
}

// Driver Code
let arr = [2, 3, 5, 6, 7];
let opr = [
    [2, 4, 2],
    [3, 4, -1]
];
let res = diffArray(arr, opr);
console.log(arr.join(" "));

Output
2 3 7 7 8 

Time Complexity: O(n × q), as each of the q operations may update up to n elements.
Auxiliary Space: O(1), since no extra space is used apart from a few variables.

[Better Approach] Using Difference Array

Instead of updating each element in the range for every operation, initialize a new array (same size as input) filled with zeros.

for each operation [l, r, v], do:

  • diff[l] += v
  • if (r + 1 < n) diff[r + 1] -= v

This marks the range updates in constant time.
Finally, compute the prefix sum of the diff[] array and add it to the original array to get the final result.

Why it works:

  • Instead of updating every element between l and r for each operation (which can be slow), we just mark where the increase starts and where it ends.
  • Imagine this like placing a +v flag at index l (start adding v), and a -v flag at index r + 1 (stop adding v after index r). You’re just saying: “Start adding v here, and stop adding v there.”
  • After placing all these flags (from all operations), you take a prefix sum — going through the array from left to right and applying the net effect of all flags.
  • This way, every element automatically receives all the right updates — without updating each one manually per operation.
C++
#include <iostream>
#include <vector>
using namespace std;

// Function to apply a single range update 
// on the difference array
void update(vector<int>& d, int l, int r, int x) {

    // Adding v at index l 
    d[l] += x;

    // Subtracting v at index r + 1 ensures the addition 
    // stops at index r when prefix sums are applied
    d[r + 1] -= x;
}

// Function to initialize difference array, handle all 
// queries, and apply prefix sum
vector<int> diffArray(vector<int>& arr, 
                        vector<vector<int>>& opr) {
    int n = arr.size();
    vector<int> d(n + 1, 0);

    // Process each operation [l, r, v]
    for (auto& query : opr) {
        int l = query[0];
        int r = query[1];
        int v = query[2];
        update(d, l, r, v);
    }

    // Apply prefix sum to get final result
    for (int i = 0; i < n; i++) {
        if (i > 0) d[i] += d[i - 1];
        arr[i] += d[i];
    }

    return arr;
}

int main() {
    vector<int> arr = {2, 3, 5, 6, 7};
    vector<vector<int>> opr = {
        {2, 4, 2},
        {3, 4, -1}
    };

    vector<int> res = diffArray(arr, opr);
    for (int i = 0; i < res.size(); i++) {
        cout << res[i] << " ";
    }
    cout << endl;

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

class GfG {

    // Function to apply a single range update 
    // on the difference array
    static void update(int[] d, int l, int r, int x) {
        d[l] += x;
        if (r + 1 < d.length) {
            d[r + 1] -= x;
        }
    }

    // Function to process operations 
    static ArrayList<Integer> diffArray(int[] arr, int[][] opr) {
        int n = arr.length;
        int[] d = new int[n + 1];

        // Apply all operations to the difference array
        for (int[] query : opr) {
            int l = query[0];
            int r = query[1];
            int v = query[2];
            update(d, l, r, v);
        }

        // Apply prefix sum and construct result
        for (int i = 0; i < n; i++) {
            if (i > 0) d[i] += d[i - 1];
            arr[i] += d[i];
        }

        // Convert array to ArrayList and return
        ArrayList<Integer> result = new ArrayList<>();
        for (int num : arr) {
            result.add(num);
        }
        return result;
    }

    public static void main(String[] args) {
        int[] arr = {2, 3, 5, 6, 7};
        int[][] opr = {
            {2, 4, 2},
            {3, 4, -1}
        };

        ArrayList<Integer> res = diffArray(arr, opr);
        for (int num : res) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}
Python
# Function to apply a single range update 
# on the difference array
def update(d, l, r, x):

    # Adding v at index l 
    d[l] += x

    # Subtracting v at index r + 1 ensures the addition 
    # stops at index r when prefix sums are applied
    if r + 1 < len(d):
        d[r + 1] -= x

 

# Function to initialize difference array, handle 
# all queries, and apply prefix sum
def diffArray(arr, opr):
    n = len(arr)
    d = [0] * (n + 1)

    # Process each operation [l, r, v]
    for l, r, v in opr:
        update(d, l, r, v)

    # Apply prefix sum to get final result
    for i in range(n):
        if i > 0:
            d[i] += d[i - 1]
        arr[i] += d[i]

    return arr


if __name__ == "__main__":
    arr = [2, 3, 5, 6, 7]
    opr = [
        [2, 4, 2],
        [3, 4, -1]
    ]

    res = diffArray(arr, opr)
    for num in res:
        print(num, end=" ")
    print()
C#
using System;
using System.Collections.Generic;

class GfG {

    // Function to apply a single range update 
    // on the difference array
    static void update(int[] d, int l, int r, int x) {
        d[l] += x;
        if (r + 1 < d.Length) {
            d[r + 1] -= x;
        }
    }

    // Function to handle all queries
    static List<int> diffArray(int[] arr, int[][] opr) {
        int n = arr.Length;
        int[] d = new int[n + 1];

        // Apply all operations using difference array
        foreach (var query in opr) {
            int l = query[0];
            int r = query[1];
            int v = query[2];
            update(d, l, r, v);
        }

        // Build the final array using prefix sum
        for (int i = 0; i < n; i++) {
            if (i > 0) d[i] += d[i - 1];
            arr[i] += d[i];
        }

        // Convert array to List<int> and return
        List<int> result = new List<int>();
        foreach (int num in arr) {
            result.Add(num);
        }
        return result;
    }

    static void Main() {
        int[] arr = {2, 3, 5, 6, 7};
        int[][] opr = new int[][] {
            new int[] {2, 4, 2},
            new int[] {3, 4, -1}
        };

        List<int> res = diffArray(arr, opr);
        foreach (int num in res) {
            Console.Write(num + " ");
        }
        Console.WriteLine();
    }
}
JavaScript
// Function to apply a single range update on 
// the difference array
function update(d, l, r, x) {

    // Adding v at index l 
    d[l] += x;

    // Subtracting v at index r + 1 ensures the addition 
    // stops at index r when prefix sums are applied
    if (r + 1 < d.length) {
        d[r + 1] -= x;
    }
}


// Function to initialize difference array, handle 
// all queries, and apply prefix sum
function diffArray(arr, opr) {
    let n = arr.length;
    let d = new Array(n + 1).fill(0);

    // Process each operation [l, r, v]
    for (let [l, r, v] of opr) {
        update(d, l, r, v);
    }

    // Apply prefix sum to get final result
    for (let i = 0; i < n; i++) {
        if (i > 0) d[i] += d[i - 1];
        arr[i] += d[i];
    }

    return arr;
}

// Driver code
let arr = [2, 3, 5, 6, 7];
let opr = [
    [2, 4, 2],
    [3, 4, -1]
];

let res = diffArray(arr, opr);
console.log(res.join(" "));

Output
2 3 7 7 8 

Time Complexity: O(n + q), O(q) for updates and O(n) for prefix sum.
Auxiliary Space: O(n), for the difference array used to store range updates.

[Efficient Approach] In-Place Difference Array for Range Updates

The in-place difference array approach works by transforming the original array into a difference array, where each element represents the change from its previous element. This allows range updates to be applied in constant time by modifying just two positions — the start and end+1 of the range. Later, taking a prefix sum reconstructs the final updated array. This works because the prefix sum of a difference array always yields the original or updated values efficiently.

Step by step approach:

  • Convert original array to difference form:
  • Update each element from right to left as arr[i] = arr[i] - arr[i - 1] for i > 0. This transforms the array into its own difference array.
  • Apply each operation [l, r, v]:
    • Do arr[l] += v to start adding v from index l.
    • Do arr[r + 1] -= v to stop adding v after index r (if r + 1 < n).
  • Restore the final array by traversing the array from left to right, adding arr[i - 1] to arr[i] to compute the prefix sum and recover the final updated values.
  • The modified array now holds the result after applying all range updates efficiently in-place.
C++
#include <iostream>
#include <vector>
using namespace std;

vector<int> diffArray(vector<int>& arr, vector<vector<int>>& opr) {
    int n = arr.size();

    // Convert arr to in-place difference array
    for (int i = n - 1; i > 0; i--) {
        arr[i] -= arr[i - 1];
    }

    // Apply each operation directly on the original array
    // Each operation is of the form [l, r, v]
    for (auto& q : opr) {
        int l = q[0], r = q[1], v = q[2];

        // Adding v at index l
        arr[l] += v;

        // Subtracting v at index r + 1 ensures the addition 
        // stops at index r when prefix sums are applied
        if (r + 1 < n) arr[r + 1] -= v;
    }

    // Take prefix sum to get the final updated array
    for (int i = 1; i < n; i++) {
        arr[i] += arr[i - 1];
    }

    return arr;
}


int main() {
    vector<int> arr = {2, 3, 5, 6, 7};
    vector<vector<int>> opr = {
        {2, 4, 2},
        {3, 4, -1}
    };

    vector<int> res = diffArray(arr, opr);
    
    for (int num : res) {
        cout << num << " ";
    }
    cout << endl;

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

class GfG {

    public static ArrayList<Integer> diffArray(int[] arr, int[][] opr) {
        int n = arr.length;

        // Convert arr to in-place difference array
        for (int i = n - 1; i > 0; i--) {
            arr[i] -= arr[i - 1];
        }

        // Apply each operation [l, r, v]
        for (int[] q : opr) {
            int l = q[0], r = q[1], v = q[2];

            arr[l] += v;
            if (r + 1 < n) arr[r + 1] -= v;
        }

        // Take prefix sum to get final array
        for (int i = 1; i < n; i++) {
            arr[i] += arr[i - 1];
        }

        // Convert array to ArrayList
        ArrayList<Integer> result = new ArrayList<>();
        for (int num : arr) {
            result.add(num);
        }

        return result;
    }

    public static void main(String[] args) {
        int[] arr = {2, 3, 5, 6, 7};
        int[][] opr = {
            {2, 4, 2},
            {3, 4, -1}
        };

        ArrayList<Integer> res = diffArray(arr, opr);
        for (int num : res) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}
Python
def diffArray(arr, opr):
    n = len(arr)

    # Convert arr to in-place difference array
    for i in range(n - 1, 0, -1):
        arr[i] -= arr[i - 1]

    # Apply each operation directly on the original array
    # Each operation is of the form [l, r, v]
    for l, r, v in opr:

        # Adding v at index l
        arr[l] += v

        # Subtracting v at index r + 1 ensures the addition 
        # stops at index r when prefix sums are applied
        if r + 1 < n:
            arr[r + 1] -= v

    # Take prefix sum to get the final updated array
    for i in range(1, n):
        arr[i] += arr[i - 1]

    return arr


if __name__ == "__main__":
    
    arr = [2, 3, 5, 6, 7]
    opr = [
        [2, 4, 2],
        [3, 4, -1]
    ]

    res = diffArray(arr, opr)
    print(*res)
C#
using System;
using System.Collections.Generic;

class GfG {

    public static List<int> diffArray(int[] arr, int[][] opr) {
        int n = arr.Length;

        // Convert arr to in-place difference array
        for (int i = n - 1; i > 0; i--) {
            arr[i] -= arr[i - 1];
        }

        // Apply each operation [l, r, v]
        foreach (var q in opr) {
            int l = q[0], r = q[1], v = q[2];
            arr[l] += v;
            if (r + 1 < n) arr[r + 1] -= v;
        }

        // Take prefix sum to restore the final array
        for (int i = 1; i < n; i++) {
            arr[i] += arr[i - 1];
        }

        // Convert array to List<int>
        List<int> result = new List<int>();
        foreach (int num in arr) {
            result.Add(num);
        }

        return result;
    }

    // Driver code
    public static void Main() {
        int[] arr = {2, 3, 5, 6, 7};
        int[][] opr = {
            new int[] {2, 4, 2},
            new int[] {3, 4, -1}
        };

        List<int> res = diffArray(arr, opr);
        foreach (int num in res) {
            Console.Write(num + " ");
        }
        Console.WriteLine();
    }
}
JavaScript
function diffArray(arr, opr) {
    let n = arr.length;

    // Convert arr to in-place difference array
    for (let i = n - 1; i > 0; i--) {
        arr[i] -= arr[i - 1];
    }

    // Apply each operation directly on the original array
    // Each operation is of the form [l, r, v]
    for (let [l, r, v] of opr) {

        // Adding v at index l
        arr[l] += v;

        // Subtracting v at index r + 1 ensures the addition 
        // stops at index r when prefix sums are applied
        if (r + 1 < n) {
            arr[r + 1] -= v;
        }
    }

    // Take prefix sum to get the final updated array
    for (let i = 1; i < n; i++) {
        arr[i] += arr[i - 1];
    }

    return arr;
}


// Driver code
let arr = [2, 3, 5, 6, 7];
let opr = [
    [2, 4, 2],
    [3, 4, -1]
];

let res = diffArray(arr, opr);
console.log(res.join(" "));

Output
2 3 7 7 8 

Time Complexity: O(n + q), O(q) for updates and O(n) for prefix sum.
Auxiliary Space: O(1), since no extra space is used apart from a few variables.


Next Article

Similar Reads