Given a positive integer K and two arrays A[] and B[] consisting of M and N positive integers from the range [1, K] respectively, the task is to minimize the count of replacements of array elements by values from the range [1, K] such that the sum of elements of both the arrays becomes equal. If it is impossible to make the sum equal, then print -1.
Examples:
Input: K = 6, A[] = {3, 4, 1}, B[] = {6, 6, 6}
Output: 2
Explanation:
One of the possible way is to replace elements of array B[] at indexes 0 and 1 with 1 in two moves. Therefore, the array B[] modifies to {1, 1, 6}.
Now, the sum of both the arrays is 8, which is equal.Input: A[] = {4, 3, 2}, B[] = {2, 3, 3, 1}, K = 6, N = 4, M = 3
Output: 0
Approach: The given problem can be solved using Two-pointer technique. Follow the steps below to solve the problem:
- Initialize 4 variables, say l1 = 0, r1 = M – 1, l2 = 0, r2 = N – 1, used to traverse the array.
- Initialize a variable, say res, to store the count of minimum replacements required.
- Sort both the given arrays in ascending order.
- Find the difference of the sum of both arrays and store it in a variable, say diff.
- Iterate until l1 ? r1 or l2 ? r2 and perform the following steps:
- If diff = 0: Break out of the loop.
- If diff exceeds 0: Take the maximum between (A[r1] – 1) and (K – B[l2]) and subtract it from the difference diff and then increment l2, if the value of (K – B[l2]) is greater. Otherwise, decrement r1 by one.
- Otherwise, take the maximum between (B[r2] – 1) and (K – A[l1]) and add it to the difference diff, then increment l1, if (K – A[l1]) is greater. Otherwise, decrement the value of r2 by 1.
- Increment the value of res by 1.
- After completing the above steps, print the value of res as the minimum number of replacements of array elements required.
Below is the implementation of the above approach:
#include <bits/stdc++.h> using namespace std;
// Function to find minimum number // of replacements required to make // the sum of two arrays equal int makeSumEqual(vector< int > a, vector< int > b,
int K, int M, int N)
{ // Stores the sum of a[]
int sum1 = 0;
// Stores the sum of b[]
int sum2 = 0;
// Calculate sum of the array a[]
for ( int el : a)
sum1 += el;
// Calculate sum of the array b[]
for ( int el : b)
sum2 += el;
// Stores the difference
// between a[] and b[]
int diff = sum1 - sum2;
// Left and Right pointer
// to traverse the array a[]
int l1 = 0, r1 = M - 1;
// Left and Right pointer
// to traverse the array b[]
int l2 = 0, r2 = N - 1;
// Stores the count of moves
int res = 0;
// Sort the arrays in
// ascending order
sort(a.begin(),a.end());
sort(b.begin(),b.end());
// Iterate while diff != 0 and
// l1 <= r1 or l2 <= r2
while (l1 <= r1 || l2 <= r2)
{
if (diff == 0)
{
break ;
}
// If diff is greater than 0
if (diff > 0)
{
// If all pointers are valid
if (l2 <= r2 && l1 <= r1)
{
if (K - b[l2] < a[r1] - 1) {
int sub = min(
a[r1] - 1, diff);
diff -= sub;
a[r1] -= sub;
r1--;
}
else {
int sub = min(
K - b[l2], diff);
diff -= sub;
b[l2] += sub;
l2++;
}
}
// Otherwise, if only pointers
// of array a[] is valid
else if (l1 <= r1) {
int sub = min(
a[r1] - 1, diff);
diff -= sub;
a[r1] -= sub;
r1--;
}
// Otherwise
else {
int sub = min(
K - b[l2], diff);
diff -= sub;
b[l2] += sub;
l2++;
}
}
// If diff is less than 0
else {
// If all pointers are valid
if (l1 <= r1 && l2 <= r2) {
if (K - a[l1]
< b[r2] - 1) {
int sub = min(
b[r2] - 1,
-1 * diff);
diff += sub;
b[r2] -= sub;
r2--;
}
else {
int sub = min(
K - a[l1],
-1 * diff);
diff += sub;
a[l1] -= sub;
l1++;
}
}
// Otherwise, if only pointers
// of array a[] is valid
else if (l2 <= r2) {
int sub
= min(
b[r2] - 1,
-1 * diff);
diff += sub;
b[r2] -= sub;
r2--;
}
// Otherwise
else {
int sub = min(
K - a[l1], diff);
diff += sub;
a[l1] += sub;
l1++;
}
}
// Increment count
// of res by one
res++;
}
// If diff is 0, then return res
if (diff == 0)
return res;
// Otherwise, return -1
else
return -1;
} // Driver Code int main()
{ vector< int > A = { 1, 4, 3 };
vector< int > B = { 6, 6, 6 };
int M = A.size();
int N = B.size();
int K = 6;
cout << makeSumEqual(A, B, K,M, N);
return 0;
} // This code is contributed by mohit kumar 29. |
// Java program for the above approach import java.util.*;
class GFG {
// Function to find minimum number
// of replacements required to make
// the sum of two arrays equal
public static int makeSumEqual(
int [] a, int [] b, int K,
int M, int N)
{
// Stores the sum of a[]
int sum1 = 0 ;
// Stores the sum of b[]
int sum2 = 0 ;
// Calculate sum of the array a[]
for ( int el : a)
sum1 += el;
// Calculate sum of the array b[]
for ( int el : b)
sum2 += el;
// Stores the difference
// between a[] and b[]
int diff = sum1 - sum2;
// Left and Right pointer
// to traverse the array a[]
int l1 = 0 , r1 = M - 1 ;
// Left and Right pointer
// to traverse the array b[]
int l2 = 0 , r2 = N - 1 ;
// Stores the count of moves
int res = 0 ;
// Sort the arrays in
// ascending order
Arrays.sort(a);
Arrays.sort(b);
// Iterate while diff != 0 and
// l1 <= r1 or l2 <= r2
while (l1 <= r1 || l2 <= r2) {
if (diff == 0 ) {
break ;
}
// If diff is greater than 0
if (diff > 0 ) {
// If all pointers are valid
if (l2 <= r2 && l1 <= r1) {
if (K - b[l2] < a[r1] - 1 ) {
int sub = Math.min(
a[r1] - 1 , diff);
diff -= sub;
a[r1] -= sub;
r1--;
}
else {
int sub = Math.min(
K - b[l2], diff);
diff -= sub;
b[l2] += sub;
l2++;
}
}
// Otherwise, if only pointers
// of array a[] is valid
else if (l1 <= r1) {
int sub = Math.min(
a[r1] - 1 , diff);
diff -= sub;
a[r1] -= sub;
r1--;
}
// Otherwise
else {
int sub = Math.min(
K - b[l2], diff);
diff -= sub;
b[l2] += sub;
l2++;
}
}
// If diff is less than 0
else {
// If all pointers are valid
if (l1 <= r1 && l2 <= r2) {
if (K - a[l1]
< b[r2] - 1 ) {
int sub = Math.min(
b[r2] - 1 ,
- 1 * diff);
diff += sub;
b[r2] -= sub;
r2--;
}
else {
int sub = Math.min(
K - a[l1],
- 1 * diff);
diff += sub;
a[l1] -= sub;
l1++;
}
}
// Otherwise, if only pointers
// of array a[] is valid
else if (l2 <= r2) {
int sub
= Math.min(
b[r2] - 1 ,
- 1 * diff);
diff += sub;
b[r2] -= sub;
r2--;
}
// Otherwise
else {
int sub = Math.min(
K - a[l1], diff);
diff += sub;
a[l1] += sub;
l1++;
}
}
// Increment count
// of res by one
res++;
}
// If diff is 0, then return res
if (diff == 0 )
return res;
// Otherwise, return -1
else
return - 1 ;
}
// Driver Code
public static void main(String[] args)
{
int [] A = { 1 , 4 , 3 };
int [] B = { 6 , 6 , 6 };
int M = A.length;
int N = B.length;
int K = 6 ;
System.out.println(
makeSumEqual(A, B, K,
M, N));
}
} |
# Python program for the above approach # Function to find minimum number # of replacements required to make # the sum of two arrays equal from functools import cmp_to_key
def cmp (c, d):
return c - d
def makeSumEqual(a, b, K, M, N):
# Stores the sum of a[]
sum1 = 0
# Stores the sum of b[]
sum2 = 0
# Calculate sum of the array a[]
for el in range ( len (a)):
sum1 + = a[el]
# Calculate sum of the array b[]
for el in range ( len (b)):
sum2 + = b[el]
# Stores the difference
# between a[] and b[]
diff = sum1 - sum2
# Left and Right pointer
# to traverse the array a[]
l1 = 0
r1 = M - 1
# Left and Right pointer
# to traverse the array b[]
l2 = 0
r2 = N - 1
# Stores the count of moves
res = 0
# Sort the arrays in
# ascending order
a.sort(key = cmp_to_key( cmp ))
b.sort(key = cmp_to_key( cmp ))
# Iterate while diff != 0 and
# l1 <= r1 or l2 <= r2
while (l1 < = r1 or l2 < = r2):
if (diff = = 0 ):
break
# If diff is greater than 0
if (diff > 0 ):
# If all pointers are valid
if (l2 < = r2 and l1 < = r1):
if (K - b[l2] < a[r1] - 1 ):
sub = min (a[r1] - 1 , diff)
diff - = sub
a[r1] - = sub
r1 - = 1
else :
sub = min (K - b[l2], diff)
diff - = sub
b[l2] + = sub
l2 + = 1
# Otherwise, if only pointers
# of array a[] is valid
elif (l1 < = r1):
sub = min (a[r1] - 1 , diff)
diff - = sub
a[r1] - = sub
r1 - = 1
# Otherwise
else :
sub = min (K - b[l2], diff)
diff - = sub
b[l2] + = sub
l2 + = 1
# If diff is less than 0
else :
# If all pointers are valid
if (l1 < = r1 and l2 < = r2):
if (K - a[l1]< b[r2] - 1 ):
sub = min (b[r2] - 1 , - 1 * diff)
diff + = sub
b[r2] - = sub
r2 - = 1
else :
sub = min (K - a[l1], - 1 * diff)
diff + = sub
a[l1] - = sub
l1 + = 1
# Otherwise, if only pointers
# of array a[] is valid
elif (l2 < = r2):
sub = min (b[r2] - 1 , - 1 * diff)
diff + = sub
b[r2] - = sub
r2 - = 1
# Otherwise
else :
sub = min (K - a[l1], diff)
diff + = sub
a[l1] + = sub
l1 + = 1
# Increment count
# of res by one
res + = 1
# If diff is 0, then return res
if (diff = = 0 ):
return res
# Otherwise, return -1
else :
return - 1
# Driver Code A = [ 1 , 4 , 3 ]
B = [ 6 , 6 , 6 ]
M = len (A)
N = len (B)
K = 6
print (makeSumEqual(A, B, K,M, N))
# This code is contributed by shinjanpatra |
// C# program to implement // the above approach using System;
public class GFG
{ // Function to find minimum number
// of replacements required to make
// the sum of two arrays equal
public static int makeSumEqual(
int [] a, int [] b, int K,
int M, int N)
{
// Stores the sum of a[]
int sum1 = 0;
// Stores the sum of b[]
int sum2 = 0;
// Calculate sum of the array a[]
foreach ( int el in a)
sum1 += el;
// Calculate sum of the array b[]
foreach ( int el in b)
sum2 += el;
// Stores the difference
// between a[] and b[]
int diff = sum1 - sum2;
// Left and Right pointer
// to traverse the array a[]
int l1 = 0, r1 = M - 1;
// Left and Right pointer
// to traverse the array b[]
int l2 = 0, r2 = N - 1;
// Stores the count of moves
int res = 0;
// Sort the arrays in
// ascending order
Array.Sort(a);
Array.Sort(b);
// Iterate while diff != 0 and
// l1 <= r1 or l2 <= r2
while (l1 <= r1 || l2 <= r2) {
if (diff == 0) {
break ;
}
// If diff is greater than 0
if (diff > 0) {
// If all pointers are valid
if (l2 <= r2 && l1 <= r1) {
if (K - b[l2] < a[r1] - 1) {
int sub = Math.Min(
a[r1] - 1, diff);
diff -= sub;
a[r1] -= sub;
r1--;
}
else {
int sub = Math.Min(
K - b[l2], diff);
diff -= sub;
b[l2] += sub;
l2++;
}
}
// Otherwise, if only pointers
// of array a[] is valid
else if (l1 <= r1) {
int sub = Math.Min(
a[r1] - 1, diff);
diff -= sub;
a[r1] -= sub;
r1--;
}
// Otherwise
else {
int sub = Math.Min(
K - b[l2], diff);
diff -= sub;
b[l2] += sub;
l2++;
}
}
// If diff is less than 0
else {
// If all pointers are valid
if (l1 <= r1 && l2 <= r2) {
if (K - a[l1]
< b[r2] - 1) {
int sub = Math.Min(
b[r2] - 1,
-1 * diff);
diff += sub;
b[r2] -= sub;
r2--;
}
else {
int sub = Math.Min(
K - a[l1],
-1 * diff);
diff += sub;
a[l1] -= sub;
l1++;
}
}
// Otherwise, if only pointers
// of array a[] is valid
else if (l2 <= r2) {
int sub
= Math.Min(
b[r2] - 1,
-1 * diff);
diff += sub;
b[r2] -= sub;
r2--;
}
// Otherwise
else {
int sub = Math.Min(
K - a[l1], diff);
diff += sub;
a[l1] += sub;
l1++;
}
}
// Increment count
// of res by one
res++;
}
// If diff is 0, then return res
if (diff == 0)
return res;
// Otherwise, return -1
else
return -1;
}
// Driver Code public static void Main(String[] args)
{ int [] A = { 1, 4, 3 };
int [] B = { 6, 6, 6 };
int M = A.Length;
int N = B.Length;
int K = 6;
Console.WriteLine(
makeSumEqual(A, B, K,
M, N));
} } |
<script> // Javascript program for the above approach // Function to find minimum number // of replacements required to make // the sum of two arrays equal function makeSumEqual(a,b,K,M,N)
{ // Stores the sum of a[]
let sum1 = 0;
// Stores the sum of b[]
let sum2 = 0;
// Calculate sum of the array a[]
for (let el=0;el< a.length;el++)
sum1 += a[el];
// Calculate sum of the array b[]
for (let el=0;el< b.length;el++)
sum2 += b[el];
// Stores the difference
// between a[] and b[]
let diff = sum1 - sum2;
// Left and Right pointer
// to traverse the array a[]
let l1 = 0, r1 = M - 1;
// Left and Right pointer
// to traverse the array b[]
let l2 = 0, r2 = N - 1;
// Stores the count of moves
let res = 0;
// Sort the arrays in
// ascending order
a.sort( function (c,d){ return c-d;});
b.sort( function (c,d){ return c-d;});
// Iterate while diff != 0 and
// l1 <= r1 or l2 <= r2
while (l1 <= r1 || l2 <= r2) {
if (diff == 0) {
break ;
}
// If diff is greater than 0
if (diff > 0) {
// If all pointers are valid
if (l2 <= r2 && l1 <= r1) {
if (K - b[l2] < a[r1] - 1) {
let sub = Math.min(
a[r1] - 1, diff);
diff -= sub;
a[r1] -= sub;
r1--;
}
else {
let sub = Math.min(
K - b[l2], diff);
diff -= sub;
b[l2] += sub;
l2++;
}
}
// Otherwise, if only pointers
// of array a[] is valid
else if (l1 <= r1) {
let sub = Math.min(
a[r1] - 1, diff);
diff -= sub;
a[r1] -= sub;
r1--;
}
// Otherwise
else {
let sub = Math.min(
K - b[l2], diff);
diff -= sub;
b[l2] += sub;
l2++;
}
}
// If diff is less than 0
else {
// If all pointers are valid
if (l1 <= r1 && l2 <= r2) {
if (K - a[l1]
< b[r2] - 1) {
let sub = Math.min(
b[r2] - 1,
-1 * diff);
diff += sub;
b[r2] -= sub;
r2--;
}
else {
let sub = Math.min(
K - a[l1],
-1 * diff);
diff += sub;
a[l1] -= sub;
l1++;
}
}
// Otherwise, if only pointers
// of array a[] is valid
else if (l2 <= r2) {
let sub
= Math.min(
b[r2] - 1,
-1 * diff);
diff += sub;
b[r2] -= sub;
r2--;
}
// Otherwise
else {
let sub = Math.min(
K - a[l1], diff);
diff += sub;
a[l1] += sub;
l1++;
}
}
// Increment count
// of res by one
res++;
}
// If diff is 0, then return res
if (diff == 0)
return res;
// Otherwise, return -1
else
return -1;
} // Driver Code let A=[1, 4, 3 ]; let B=[6, 6, 6 ]; let M = A.length; let N = B.length; let K = 6; document.write(makeSumEqual(A, B, K, M, N));
// This code is contributed by unknown2108 </script> |
2
Time Complexity: O(N*log(N)+M*log(M))
Auxiliary Space: O(1)