Skip to content
Related Articles

Related Articles

Minimize replacements with values up to K to make sum of two given arrays equal
  • Last Updated : 05 Mar, 2021

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: 1

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:

C++




#include <bits/stdc++.h>
using namespace std;
 
// Functon 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




// Java program for the above approach
import java.util.*;
 
class GFG {
 
    // Functon 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));
    }
}

C#




// C# program to implement
// the above approach
using System;
 
public class GFG
{
   
    // Functon 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));
}
}
Output: 
2

 

Time Complexity: O(N)
Auxiliary Space: O(1)

Attention reader! Don’t stop learning now. Get hold of all the important mathematical concepts for competitive programming with the Essential Maths for CP Course at a student-friendly price. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

My Personal Notes arrow_drop_up
Recommended Articles
Page :