Open In App

Minimize replacements with values up to K to make sum of two given arrays equal

Improve
Improve
Like Article
Like
Save
Share
Report

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:

C++




#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




// 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));
    }
}


Python3




# 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#




// 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));
}
}


Javascript




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


Output: 

2

 

Time Complexity: O(N*log(N)+M*log(M))
Auxiliary Space: O(1)



Last Updated : 20 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads