Given two arrays arr1[] and arr2[] of size N and M (M < N) add all elements of arr2[] in all possible subarrays of arr1[] of size M exactly once. The task is to return the final array arr1[] after performing the above operations.
Examples:
Input: arr1[] = {1, 1, 1, 1, 1}, arr2[] = {1, 1, 1}
Output: 2 3 4 3 2
Explanation: There are exactly 3 subarrays of size M in arr1[]
adding corresponding elements of arr2[] in first subarray from element 1 to 3. arr1[] becomes {2, 2, 2, 1, 1}
adding corresponding elements of arr2[] in second subarray from element 2 to 4. arr1[] becomes {2, 3, 3, 2, 1}
adding corresponding elements of arr2[] in the third subarray from elements 3 to 5. arr1[] becomes {2, 3, 4, 3, 2}Input: arr1[] = {1, 2, 3, 4, 5}, arr2[] = {10}
Output: 11 12 13 14 15
Naive Approach: The problem can be solved using linear iteration based on the following idea:
Keep adding all elements of arr2[] in all possible subarrays of size M of arr1[]. There will be exactly N – M + 1 subarrays.
Follow the steps mentioned below to implement the idea:
-
Iterate from i = 0 to N-M+1:
-
Iterate from j = 0 to M:
- Add arr2[j] with arr[i+j.
-
Iterate from j = 0 to M:
- Return the final state of arr1[] as the required answer.
Below is the implementation of the above approach.
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// Function to find the final state of arr1[] void addArr2ToArr1( int arr1[], int arr2[], int N, int M)
{ // Iterating through all possible subarrays
// of size M in arr1[] there will be
// exactly N - M + 1 subarrays
for ( int i = 0; i < N - M + 1; i++) {
// Iterating through M elements of arr2[]
// and adding in arr1[]'s 'i'th subarray's
// 'i + j' th element
for ( int j = 0; j < M; j++) {
arr1[i + j] = arr1[i + j] + arr2[j];
}
}
// Printing finally array
for ( int i = 0; i < N; i++) {
cout << arr1[i] << " " ;
}
cout << endl;
} // Driver program int main()
{ int arr1[] = { 1, 1, 1, 1, 1 }, arr2[] = { 1, 1, 1 };
int N = sizeof (arr1) / sizeof (arr1[0]);
int M = sizeof (arr2) / sizeof (arr2[0]);
// Function call for testcase 1
addArr2ToArr1(arr1, arr2, N, M);
int arr3[] = { 10, 11, 12, 13, 14 }, arr4[] = { 10 };
int N2 = sizeof (arr3) / sizeof (arr3[0]);
int M2 = sizeof (arr4) / sizeof (arr4[0]);
// Function call for testcase 2
addArr2ToArr1(arr3, arr4, N2, M2);
int arr5[] = { 12, 11, 10, 9 },
arr6[] = { 1, 2, 3, 4, 5 };
int N3 = sizeof (arr5) / sizeof (arr5[0]);
int M3 = sizeof (arr6) / sizeof (arr6[0]);
// Function call for testcase 3
addArr2ToArr1(arr5, arr6, N3, M3);
return 0;
} |
// Java code to implement the approach import java.io.*;
class GFG {
// Function to find the final state of arr1[]
static void addArr2ToArr1( int [] arr1, int [] arr2, int N,
int M)
{
// Iterating through all possible subarrays
// of size M in arr1[] there will be
// exactly N - M + 1 subarrays
for ( int i = 0 ; i < N - M + 1 ; i++) {
// Iterating through M elements of arr2[]
// and adding in arr1[]'s 'i'th subarray's
// 'i + j' th element
for ( int j = 0 ; j < M; j++) {
arr1[i + j] = arr1[i + j] + arr2[j];
}
}
// Printing finally array
for ( int i = 0 ; i < N; i++) {
System.out.print(arr1[i] + " " );
}
System.out.println();
}
public static void main(String[] args)
{
int [] arr1 = { 1 , 1 , 1 , 1 , 1 };
int [] arr2 = { 1 , 1 , 1 };
int N = arr1.length;
int M = arr2.length;
// Function call for testcase 1
addArr2ToArr1(arr1, arr2, N, M);
int [] arr3 = { 10 , 11 , 12 , 13 , 14 };
int [] arr4 = { 10 };
int N2 = arr3.length;
int M2 = arr4.length;
// Function call for testcase 2
addArr2ToArr1(arr3, arr4, N2, M2);
int [] arr5 = { 12 , 11 , 10 , 9 };
int [] arr6 = { 1 , 2 , 3 , 4 , 5 };
int N3 = arr5.length;
int M3 = arr6.length;
// Function call for testcase 3
addArr2ToArr1(arr5, arr6, N3, M3);
}
} // This code is contributed by lokesh. |
# python code # Function to find the final state of arr1[] def addArr2ToArr1(arr1, arr2, N, M):
# Iterating through all possible subarrays
# of size M in arr1[] there will be
# exactly N - M + 1 subarrays
for i in range ( 0 , N - M + 1 ):
# Iterating through M elements of arr2[]
# and adding in arr1[]'s 'i'th subarray's
# 'i + j' th element
for j in range ( 0 , M):
arr1[i + j] = arr1[i + j] + arr2[j]
# Printing finally array
for i in range ( 0 , N):
print (arr1[i], end = " " )
print ()
# Driver program arr1 = [ 1 , 1 , 1 , 1 , 1 ]
arr2 = [ 1 , 1 , 1 ]
N = len (arr1)
M = len (arr2)
# Function call for testcase 1 addArr2ToArr1(arr1, arr2, N, M) arr3 = [ 10 , 11 , 12 , 13 , 14 ]
arr4 = [ 10 ]
N2 = len (arr3)
M2 = len (arr4)
# Function call for testcase 2 addArr2ToArr1(arr3, arr4, N2, M2) arr5 = [ 12 , 11 , 10 , 9 ]
arr6 = [ 1 , 2 , 3 , 4 , 5 ]
N3 = len (arr5)
M3 = len (arr6)
# Function call for testcase 3 addArr2ToArr1(arr5, arr6, N3, M3) # This code is contributed by ksam24000 |
// C# code to implement the approach using System;
class GFG {
// Function to find the final state of arr1[]
static void addArr2ToArr1( int [] arr1, int [] arr2, int N,
int M)
{
// Iterating through all possible subarrays
// of size M in arr1[] there will be
// exactly N - M + 1 subarrays
for ( int i = 0; i < N - M + 1; i++) {
// Iterating through M elements of arr2[]
// and adding in arr1[]'s 'i'th subarray's
// 'i + j' th element
for ( int j = 0; j < M; j++) {
arr1[i + j] = arr1[i + j] + arr2[j];
}
}
// Printing finally array
for ( int i = 0; i < N; i++) {
Console.Write(arr1[i] + " " );
}
Console.WriteLine();
}
// Driver program
public static void Main()
{
int [] arr1 = { 1, 1, 1, 1, 1 };
int [] arr2 = { 1, 1, 1 };
int N = arr1.Length;
int M = arr2.Length;
// Function call for testcase 1
addArr2ToArr1(arr1, arr2, N, M);
int [] arr3 = { 10, 11, 12, 13, 14 };
int [] arr4 = { 10 };
int N2 = arr3.Length;
int M2 = arr4.Length;
// Function call for testcase 2
addArr2ToArr1(arr3, arr4, N2, M2);
int [] arr5 = { 12, 11, 10, 9 };
int [] arr6 = { 1, 2, 3, 4, 5 };
int N3 = arr5.Length;
int M3 = arr6.Length;
// Function call for testcase 3
addArr2ToArr1(arr5, arr6, N3, M3);
}
} // This code is contributed by Samim Hossain Mondal. |
// Function to find the final state of arr1[] function addArr2ToArr1(arr1, arr2, N, M) {
// Iterating through all possible subarrays
// of size M in arr1[] there will be
// exactly N - M + 1 subarrays
for (let i = 0; i < N - M + 1; i++) {
// Iterating through M elements of arr2[]
// and adding in arr1[]'s 'i'th subarray's
// 'i + j' th element
for (let j = 0; j < M; j++) {
arr1[i + j] = arr1[i + j] + arr2[j];
}
}
// Printing finally array
for (let i = 0; i < N; i++) {
console.log(arr1[i]);
}
console.log();
} // Driver program let arr1 = [1, 1, 1, 1, 1]; let arr2 = [1, 1, 1]; let N = arr1.length; let M = arr2.length; // Function call for testcase 1 addArr2ToArr1(arr1, arr2, N, M); let arr3 = [10, 11, 12, 13, 14]; let arr4 = [10]; let N2 = arr3.length; let M2 = arr4.length; // Function call for testcase 2 addArr2ToArr1(arr3, arr4, N2, M2); let arr5 = [12, 11, 10, 9]; let arr6 = [1, 2, 3, 4, 5]; let N3 = arr5.length; let M3 = arr6.length; // Function call for testcase 3 addArr2ToArr1(arr5, arr6, N3, M3); |
2 3 4 3 2 20 21 22 23 24 12 11 10 9
Time Complexity: O(N * M)
Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized based on the following idea:
This can be observed every element i of arr1[] will have some range of elements from arr2[] that gets added.
For example.
in case of arr1[] = {0, 0, 0, 0, 0}, arr2[] = {1, 2, 3}
element 1 will have 1 in its sum. Range of elements that got added from arr2[] is [0, 0].
element 2 will have 1 and 2 in its sum. Range of elements that got added from arr2[] is [0, 1].
element 3 will have 1, 2, and 3 in its sum. Range of elements that got added from arr2[] is [0, 2].
element 4 will have 2 and 3 in its sum. Range of elements that got added of arr2[] is [1, 2].
element 5 will have 3 in its sum. Range of elements that got added of arr2[] is [2, 2].Observation: every element ‘i’ will have sum of elements of arr2[] from max(0, M – N + i) to min(i, M-1).
Sum from max(1, M – N + i) to min(i, M-1) can be calculated using prefix sum in constant time.
Follow the steps below to solve the problem:
- Initializing prefix[] array which will be used to store the sum of all ranges of arr2[].
- Initializing L = max(1, M – N + i) and R = min(i, M).
- Traverse from 1 to N, Adding prefix[R] – prefix[L – 1] in arr[i – 1] .
- print the final array
Below is the implementation of the above approach.
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// Function to add corresponding // elements of arr2[] in all possible // subarrays of size M of arr1[] void addArr2ToArr1( int arr1[], int arr2[], int N, int M)
{ // Prefix sum array will be used
// to store sum of all ranges of arr2[]
int prefix[M + 1] = { 0 };
// Taking prefix sum
for ( int i = 1; i <= M; i++) {
prefix[i] = prefix[i - 1] + arr2[i - 1];
}
for ( int i = 1; i <= N; i++) {
// Add element i of arr1[] with range of
// elements of arr2[] from l to r
int r = min(i, M), l = max(1, M - N + i);
// Every element 'i' of arr1[] will
// have sum of elements of arr2[] from
// max(1, M - N + i) to min(i, M-1) which
// can be calculate using prefix
// sum in constant time
arr1[i - 1]
= arr1[i - 1] + prefix[r] - prefix[l - 1];
}
for ( int i = 0; i < N; i++) {
cout << arr1[i] << " " ;
}
} // Driver program int main()
{ int arr1[] = { 1, 1, 1, 1, 1 }, arr2[] = { 1, 1, 1 };
int N = sizeof (arr1) / sizeof (arr1[0]);
int M = sizeof (arr2) / sizeof (arr2[0]);
// Function call
addArr2ToArr1(arr1, arr2, N, M);
return 0;
} |
// Java code to implement the approach import java.util.*;
public class GFG {
// Function to add corresponding
// elements of arr2[] in all possible
// subarrays of size M of arr1[]
static void addArr2ToArr1( int arr1[], int arr2[], int N,
int M)
{
// Prefix sum array will be used
// to store sum of all ranges of arr2[]
int prefix[] = new int [M + 1 ];
for ( int i = 0 ; i < M + 1 ; i++) {
prefix[i] = 0 ;
}
// Taking prefix sum
for ( int i = 1 ; i <= M; i++) {
prefix[i] = prefix[i - 1 ] + arr2[i - 1 ];
}
for ( int i = 1 ; i <= N; i++) {
// Add element i of arr1[] with range of
// elements of arr2[] from l to r
int r = Math.min(i, M);
int l = Math.max( 1 , M - N + i);
// Every element 'i' of arr1[] will
// have sum of elements of arr2[] from
// max(1, M - N + i) to min(i, M-1) which
// can be calculate using prefix
// sum in constant time
arr1[i - 1 ]
= arr1[i - 1 ] + prefix[r] - prefix[l - 1 ];
}
for ( int i = 0 ; i < N; i++) {
System.out.print(arr1[i] + " " );
}
}
// Driver program
public static void main(String args[])
{
int arr1[] = { 1 , 1 , 1 , 1 , 1 };
int arr2[] = { 1 , 1 , 1 };
int N = arr1.length;
int M = arr2.length;
// Function call
addArr2ToArr1(arr1, arr2, N, M);
}
} // This code is contributed by Samim Hossain Mondal. |
# Python code to implement the approach def addArr2toArr1(arr1, arr2, n, m):
# Prefix sum array will be used
# to store sum for all ranges of arr2[]
prefix = []
for i in range (m + 1 ):
prefix.append( 0 )
# Taking prefix sum
for i in range ( 1 , m + 1 ):
prefix[i] = prefix[i - 1 ] + arr2[i - 1 ]
for i in range ( 1 , n + 1 ):
# Add elements i of arr1 with range of
# elements of arr2 from 1 to r
r = int ( min (i, m))
l = int ( max ( 1 , m - n + i))
# Every element 'i' of arr1 will
# have sum of elements of arr2 from
# max(1, m-n+1) to min(1, m-1) which
# can be calculated using prefix
# sum in constant time
arr1[i - 1 ] = arr1[i - 1 ] + prefix[r] - prefix[l - 1 ]
for i in range (n):
print (arr1[i], end = " " )
arr1 = [ 1 , 1 , 1 , 1 , 1 ]
arr2 = [ 1 , 1 , 1 ]
# function call addArr2toArr1(arr1, arr2, len (arr1), len (arr2))
|
// C# code to implement the approach using System;
public class GFG {
// Function to add corresponding
// elements of arr2[] in all possible
// subarrays of size M of arr1[]
static void addArr2ToArr1( int [] arr1, int [] arr2, int N,
int M)
{
// Prefix sum array will be used
// to store sum of all ranges of arr2[]
int [] prefix = new int [M + 1];
for ( int i = 0; i < M + 1; i++) {
prefix[i] = 0;
}
// Taking prefix sum
for ( int i = 1; i <= M; i++) {
prefix[i] = prefix[i - 1] + arr2[i - 1];
}
for ( int i = 1; i <= N; i++) {
// Add element i of arr1[] with range of
// elements of arr2[] from l to r
int r = Math.Min(i, M);
int l = Math.Max(1, M - N + i);
// Every element 'i' of arr1[] will
// have sum of elements of arr2[] from
// max(1, M - N + i) to min(i, M-1) which
// can be calculate using prefix
// sum in constant time
arr1[i - 1]
= arr1[i - 1] + prefix[r] - prefix[l - 1];
}
for ( int i = 0; i < N; i++) {
Console.Write(arr1[i] + " " );
}
}
static public void Main()
{
// Code
int [] arr1 = { 1, 1, 1, 1, 1 };
int [] arr2 = { 1, 1, 1 };
int N = arr1.Length;
int M = arr2.Length;
// Function call
addArr2ToArr1(arr1, arr2, N, M);
}
} // This code is contributed by lokeshmvs21. |
function addArr2toArr1(arr1, arr2, n, m) {
// Prefix sum array will be used
// to store sum for all ranges of arr2[]
var prefix = [];
for ( var i = 0; i <= m; i++) {
prefix.push(0);
}
// Taking prefix sum
for ( var i = 1; i <= m; i++) {
prefix[i] = prefix[i - 1] + arr2[i - 1];
}
for ( var i = 1; i <= n; i++) {
// Add elements i of arr1 with range of
// elements of arr2 from 1 to r
var r = Math.min(i, m);
var l = Math.max(1, m - n + i);
// Every element 'i' of arr1 will
// have sum of elements of arr2 from
// max(1, m-n+1) to min(1, m-1) which
// can be calculated using prefix
// sum in constant time
arr1[i - 1] = arr1[i - 1] + prefix[r] - prefix[l - 1];
}
for ( var i = 0; i < n; i++) {
console.log(arr1[i]);
}
} var arr1 = [1, 1, 1, 1, 1];
var arr2 = [1, 1, 1];
// function call addArr2toArr1(arr1, arr2, arr1.length, arr2.length); |
2 3 4 3 2
Time Complexity: O(M + N)
Auxiliary Space: O(M)
Related Articles:
- Introduction to Arrays – Data Structure and Algorithm Tutorials
- Prefix Sum Array – Implementation and Applications in Competitive Programming