Given an integer array arr[] and Q queries, the task is to find the sum of the array for each query of the following type:
- Each query contains 2 integers X and Y, where all the occurrences of X in arr[] are to be replaced by Y.
- After each query, they print the sum of the array.
Examples:
Input: arr[] = { 1, 2, 1, 3, 2}, X[] = { 2, 3, 5 }, Y[] = { 3, 1, 2 }
Output: 11 5 5
Explanation:
After the 1st query, replace 2 with 3, arr[] = { 1, 3, 1, 3, 3 }, Sum = 11.
After the 2nd query, replace 3 with 1, arr[] = { 1, 1, 1, 1, 1 }, Sum = 5.
After the 3rd query, replace 5 with 2, arr[] = { 1, 1, 1, 1, 1 }, Sum = 5.
Input: arr[] = { 12, 22, 11, 11, 2}, X[] = {2, 11, 22}, Y[] = {12, 222, 2}
Output: 68 490 470
Naive Approach:
The simplest approach to solve the problem mentioned above is to traverse through the array and replace all the instances of X with Y for each query and calculate the sum.
Time Complexity: O(N * Q)
Efficient Approach:
To optimize the above method, follow the steps given below:
- Precompute and store the sum of the array in a variable S and store the frequencies of array elements in a Map count.
- Then, do the following for each query:
- Find the frequency of X stored on the map.
- Subtract X * count[X] from S.
- Set count[Y] = count[X] and then count[X] = 0.
- Add Y * count[Y] to S.
- Print the updated value of S.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void sumOfTheArrayForQuery( int * A, int N,
int * X, int * Y,
int Q)
{
int sum = 0;
unordered_map< int , int > count;
for ( int i = 0; i < N; i++) {
sum += A[i];
count[A[i]]++;
}
for ( int i = 0; i < Q; i++) {
int x = X[i], y = Y[i];
sum -= count[X[i]] * X[i];
sum += count[X[i]] * Y[i];
count[Y[i]] += count[X[i]];
count[X[i]] = 0;
cout << sum << " " ;
}
}
int main()
{
int arr[] = { 1, 2, 1, 3, 2 };
int X[] = { 2, 3, 5 };
int Y[] = { 3, 1, 2 };
int N = sizeof (arr) / sizeof (arr[0]);
int Q = sizeof (X) / sizeof (X[0]);
sumOfTheArrayForQuery(arr, N, X, Y, Q);
return 0;
}
|
Java
import java.util.*;
class GFG{
public static void sumOfTheArrayForQuery( int [] A, int N,
int [] X, int [] Y,
int Q)
{
int sum = 0 ;
HashMap<Integer,
Integer> count = new HashMap<>();
for ( int i = 0 ; i < N; i++)
{
sum += A[i];
if (count.containsKey(A[i]))
{
count.replace(A[i],
count.get(A[i]) + 1 );
}
else
{
count.put(A[i], 1 );
}
}
for ( int i = 0 ; i < Q; i++)
{
int x = X[i], y = Y[i];
if (count.containsKey(X[i]))
{
sum -= count.get(X[i]) * X[i];
sum += count.get(X[i]) * Y[i];
}
if (count.containsKey(Y[i]) &&
count.containsKey(X[i]))
{
count.replace(Y[i],
count.get(Y[i]) +
count.get(X[i]));
}
if (count.containsKey(X[i]))
{
count.replace(X[i], 0 );
}
System.out.print(sum + " " );
}
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 1 , 3 , 2 };
int X[] = { 2 , 3 , 5 };
int Y[] = { 3 , 1 , 2 };
int N = arr.length;
int Q = X.length;
sumOfTheArrayForQuery(arr, N,
X, Y, Q);
}
}
|
Python3
def sumOfTheArrayForQuery(A, N, X, Y, Q):
sum = 0
count = {}
for i in range (N):
sum + = A[i]
if A[i] in count:
count[A[i]] + = 1
else :
count[A[i]] = 1
for i in range (Q):
x = X[i]
y = Y[i]
if X[i] not in count:
count[X[i]] = 0
if Y[i] not in count:
count[Y[i]] = 0
sum - = (count[X[i]] * X[i])
sum + = count[X[i]] * Y[i]
count[Y[i]] + = count[X[i]]
count[X[i]] = 0
print ( sum , end = " " )
arr = [ 1 , 2 , 1 , 3 , 2 , ]
X = [ 2 , 3 , 5 ]
Y = [ 3 , 1 , 2 ]
N = len (arr)
Q = len (X)
sumOfTheArrayForQuery(arr, N, X, Y, Q)
|
C#
using System;
using System.Collections.Generic;
class GFG{
public static void sumOfTheArrayForQuery( int [] A, int N,
int [] X, int [] Y,
int Q)
{
int sum = 0;
Dictionary< int ,
int > count = new Dictionary< int ,
int >();
for ( int i = 0; i < N; i++)
{
sum += A[i];
if (count.ContainsKey(A[i]))
{
count[A[i]]= count[A[i]] + 1;
}
else
{
count.Add(A[i], 1);
}
}
for ( int i = 0; i < Q; i++)
{
int x = X[i], y = Y[i];
if (count.ContainsKey(X[i]))
{
sum -= count[X[i]] * X[i];
sum += count[X[i]] * Y[i];
}
if (count.ContainsKey(Y[i]) &&
count.ContainsKey(X[i]))
{
count[Y[i]] = count[Y[i]] +
count[X[i]];
}
if (count.ContainsKey(X[i]))
{
count[X[i]] = 0;
}
Console.Write(sum + " " );
}
}
public static void Main(String[] args)
{
int []arr = {1, 2, 1, 3, 2};
int []X = {2, 3, 5};
int []Y = {3, 1, 2};
int N = arr.Length;
int Q = X.Length;
sumOfTheArrayForQuery(arr, N,
X, Y, Q);
}
}
|
Javascript
<script>
function sumOfTheArrayForQuery(A, N, X, Y, Q)
{
var sum = 0;
var count = new Map();
for ( var i = 0; i < N; i++) {
sum += A[i];
if (count.has(A[i]))
count.set(A[i], count.get(A[i])+1)
else
count.set(A[i], 1)
}
for ( var i = 0; i < Q; i++) {
var x = X[i], y = Y[i];
if (count.has(X[i]))
{
sum -= count.get(X[i]) * X[i];
sum += count.get(X[i]) * Y[i];
}
if (count.has(Y[i]))
{
count.set(Y[i], count.get(Y[i]) + count.get(X[i]));
}
count.set(X[i] , 0);
document.write( sum + " " );
}
}
var arr = [1, 2, 1, 3, 2];
var X = [2, 3, 5 ];
var Y = [3, 1, 2 ];
var N = arr.length;
var Q = X.length;
sumOfTheArrayForQuery(arr, N, X, Y, Q);
</script>
|
Time Complexity: O(N+Q), as each query has a computational complexity of O(1).
Auxiliary Space: O(N)