Difference Array | Range update query in O(1) (original) (raw)
Last Updated : 05 May, 2025
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]
: Addsx
to all elements fromarr[l]
toarr[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 60Explanation: [1, 0, 1, 10]: Adds 10 to
arr[0]
andarr[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]
, andarr[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
.
Table of Content
- [Naive Approach] Using loops for each queries - O(n * q) time and O(1) space
- [Expected Approach] Using Difference Array
**[Naive Approach] **Using loops for each queries - O(n * q) time and O(1) space
A **simple solution is to do following :
- update(l, r, x) : Run a loop from l to r and add x to all elements from arr[l] to arr[r]
- printArray() : Simply print arr[].
C++ `
#include #include using namespace std;
void update(vector &arr, int l, int r, int x) { for (int i = l; i <= r; i++) { arr[i] += x; } }
void printArray(const vector &arr) { for (int num : arr) { cout << num << " "; } cout << endl; }
int main() { vector 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.
- 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
- 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 #include using namespace std;
vector initDiffArray(vector &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 &d, int l, int r, int x) { d[l] += x; d[r + 1] -= x; }
void printArray(vector &arr, vector &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 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)