Open In App

Minimize moves to make Array elements equal by incrementing and decrementing pairs

Given an array arr[] of size N, the task is to print the minimum number of moves needed to make all array elements equal by selecting any two distinct indices and then increment the element at the first selected index and decrement the element at the other selected index by 1 in each move. If it is impossible to make all the array elements equal then print “-1“.

Examples



Input: arr[] = {5, 4, 1, 10}
Output: 5
Explanation: 
One of the possible way to perform operation is:
Operation 1: Select the indices 1 and 3 and then increment arr[1] by 1 and decrement arr[3] by 1. Thereafter, the array modifies to {5, 5, 1, 9}.
Operation 2: Select the indices 2 and 3 and then increment arr[2] by 1 and decrement arr[3] by 1. Thereafter, the array modifies to {5, 5, 2, 8}.
Operation 3: Select the indices 2 and 3 and then increment arr[2] by 1 and decrement arr[3] by 1. Thereafter, the array modifies to {5, 5, 3, 7}.
Operation 4: Select the indices 2 and 3 and then increment arr[2] by 1 and decrement arr[3] by 1. Thereafter, the array modifies to {5, 5, 4, 6}.
Operation 5: Select the indices 2 and 3 and then increment arr[2] by 1 and decrement arr[3] by 1. Thereafter, the array modifies to {5, 5, 5, 5}.
Therefore, the total number of move needed is 5. Also, it is the minimum possible moves needed.

Input: arr[] = {1, 4}
Output: -1



Approach: The given problem can be solved based on the following observations: 

  • It can be observed that in one move the sum of the array remains the same therefore, if the sum of the array is not divisible N then it is impossible to make all the array elements equal.
  • Otherwise, each array element will be equal to the sum of the array divided by N.
  • Therefore, the idea is to use the two pointer technique to find the minimum count of moves needed to make all the array elements equal to the sum/N.

Follow the steps below to solve the problem:

Below is the implementation of the above approach:




// C++ Program for the above approach
#include <algorithm>
#include <iostream>
using namespace std;
 
// Function to find the minimum
// operations to make the array
// elements equal
int find(int arr[], int N)
{
  // Stores the sum of the
  // array
  int Sum = 0;
  for (int i = 0; i < N; i++) {
    Sum += arr[i];
  }
  if (Sum % N) {
    return -1;
  }
 
  // update sum
  Sum /= N;
 
  // sort array
  sort(arr, arr + N);
 
  // Store the minimum
  // needed moves
  int ans = 0;
  int i = 0, j = N - 1;
 
  // Iterate until i
  // is less than j
  while (i < j) {
    if (Sum - arr[i] < arr[j] - Sum) {
 
      // Increment ans by
      // Sum-arr[i]
      ans += (Sum - arr[i]);
 
      // update
      arr[i] += (Sum - arr[i]);
      arr[j] -= (Sum - arr[i]);
 
      // Increment i by 1
      i++;
    }
    else {
 
      // Increment ans by
      //arr[j]-Sum
      ans += (arr[j] - Sum);
 
      // Update
      arr[i] += (arr[j] - Sum);
      arr[j] -= (arr[j] - Sum);
 
      // Decrement j by 1
      j--;
    }
  }
 
  // Return the value in ans
  return ans;
}
 
// Driver code
int main()
{
 
  // Given input
  int arr[] = { 5, 4, 1, 10 };
  int N = sizeof(arr) / sizeof(int);
 
  // Function call
  cout << find(arr, N);
  return 0;
}
 
// This code is contributed by Parth Manchanda




import java.util.Arrays;
 
// Java Program for the above approach
 
class GFG {
 
    // Function to find the minimum
    // operations to make the array
    // elements equal
    public static int find(int arr[], int N)
    {
       
        // Stores the sum of the
        // array
        int Sum = 0;
        for (int i = 0; i < N; i++) {
            Sum += arr[i];
        }
        if (Sum % N > 0) {
            return -1;
        }
 
        // update sum
        Sum /= N;
 
        // sort array
        Arrays.sort(arr);
 
        // Store the minimum
        // needed moves
        int ans = 0;
        int i = 0, j = N - 1;
 
        // Iterate until i
        // is less than j
        while (i < j) {
            if (Sum - arr[i] < arr[j] - Sum) {
 
                // Increment ans by
                // Sum-arr[i]
                ans += (Sum - arr[i]);
 
                // update
                arr[i] += (Sum - arr[i]);
                arr[j] -= (Sum - arr[i]);
 
                // Increment i by 1
                i++;
            } else {
 
                // Increment ans by
                // arr[j]-Sum
                ans += (arr[j] - Sum);
 
                // Update
                arr[i] += (arr[j] - Sum);
                arr[j] -= (arr[j] - Sum);
 
                // Decrement j by 1
                j--;
            }
        }
 
        // Return the value in ans
        return ans;
    }
 
    // Driver code
    public static void main(String args[]) {
 
        // Given input
        int arr[] = { 5, 4, 1, 10 };
        int N = arr.length;
 
        // Function call
        System.out.println(find(arr, N));
 
    }
}
 
// This code is contributed by gfgking




# Python program for the above approach
 
# Function to find the minimum
# operations to make the array
# elements equal
def find(arr, N):
 
    # Stores the sum of the
    # array
    Sum = sum(arr)
 
    # If sum is not divisible
    # by N
    if Sum % N:
        return -1
    else:
 
       # Update sum
        Sum //= N
 
        # Sort the array
        arr.sort()
 
        # Store the minimum
        # needed moves
        ans = 0
 
        i = 0
        j = N-1
 
        # Iterate until i
        # is less than j
        while i < j:
 
            # If the Sum-arr[i]
            # is less than the
            # arr[j]-sum
            if Sum-arr[i] < arr[j]-Sum:
 
                # Increment ans by
                # Sum-arr[i]
                ans += Sum-arr[i]
 
                # Update
                arr[i] += Sum-arr[i]
                arr[j] -= Sum-arr[i]
 
                # Increment i by 1
                i += 1
                 
            # Otherwise,
            else:
 
                # Increment ans by
                # arr[j]-Sum
                ans += arr[j]-Sum
 
                # Update
                arr[i] += arr[j]-Sum
                arr[j] -= arr[j]-Sum
 
                # Decrement j by 1
                j -= 1
 
        # Return the value in ans
        return ans
 
# Driver Code
if __name__ == '__main__':
     
    # Given Input
    arr = [5, 4, 1, 10]
    N = len(arr)
     
    # Function Call
    print(find(arr, N))




// C# program for the above approach
using System;
 
class GFG{
     
// Function to find the minimum
// operations to make the array
// elements equal
public static int find(int[] arr, int N)
{
     
    // Stores the sum of the
    // array
    int Sum = 0;
    int i = 0;
     
    for(i = 0; i < N; i++)
    {
        Sum += arr[i];
    }
    if (Sum % N > 0)
    {
        return -1;
    }
 
    // update sum
    Sum /= N;
 
    // sort array
    Array.Sort(arr);
 
    // Store the minimum
    // needed moves
    int ans = 0;
    i = 0;
    int j = N - 1;
 
    // Iterate until i
    // is less than j
    while (i < j)
    {
        if (Sum - arr[i] < arr[j] - Sum)
        {
             
            // Increment ans by
            // Sum-arr[i]
            ans += (Sum - arr[i]);
 
            // update
            arr[i] += (Sum - arr[i]);
            arr[j] -= (Sum - arr[i]);
 
            // Increment i by 1
            i++;
        }
        else
        {
             
            // Increment ans by
            // arr[j]-Sum
            ans += (arr[j] - Sum);
 
            // Update
            arr[i] += (arr[j] - Sum);
            arr[j] -= (arr[j] - Sum);
 
            // Decrement j by 1
            j--;
        }
    }
 
    // Return the value in ans
    return ans;
}
 
// Driver code
static public void Main()
{
     
    // Given input
    int[] arr = { 5, 4, 1, 10 };
    int N = arr.Length;
 
    // Function call
    Console.WriteLine(find(arr, N));
}
}
 
// This code is contributed by target_2




<script>
 
        // JavaScript Program for the above approach
 
 
        // Function to find the minimum
        // operations to make the array
        // elements equal
        function find(arr, N) {
 
            // Stores the sum of the
            // array
            let Sum = 0;
 
            for (i = 0; i < arr.length; i++) {
                Sum = Sum + arr[i];
            }
 
            // If sum is not divisible
            // by N
            if (Sum % N)
                return -1;
            else {
 
                // Update sum
                Sum = Math.floor(Sum / N);
 
                // Sort the array
                arr.sort(function (a, b) { return a - b });
 
                // Store the minimum
                // needed moves
                ans = 0
 
                i = 0
                j = N - 1
 
                // Iterate until i
                // is less than j
                while (i < j) {
 
                    // If the Sum-arr[i]
                    // is less than the
                    // arr[j]-sum
                    if (Sum - arr[i] < arr[j] - Sum) {
 
                        // Increment ans by
                        // Sum-arr[i]
                        ans += Sum - arr[i]
 
                        // Update
                        arr[i] += Sum - arr[i]
                        arr[j] -= Sum - arr[i]
 
                        // Increment i by 1
                        i += 1
                    }
                    // Otherwise,
                    else {
 
                        // Increment ans by
                        // arr[j]-Sum
                        ans += arr[j] - Sum
 
                        // Update
                        arr[i] += arr[j] - Sum
                        arr[j] -= arr[j] - Sum
 
                        // Decrement j by 1
                        j -= 1
                    }
 
                }
            }
            // Return the value in ans
            return ans;
 
        }
 
        // Driver Code
 
 
        // Given Input
        let arr = [5, 4, 1, 10];
        let N = arr.length;
 
        // Function Call
        document.write(find(arr, N));
 
 
    // This code is contributed by Potta Lokesh
     
</script>

Output
5

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

Another Approach:

Below is the implementation of above approach:




#include <algorithm>
#include <iostream>
using namespace std;
  
int find(int arr[], int N) {
    int Sum = 0;
    for (int i = 0; i < N; i++) {
        Sum += arr[i];
    }
    if (Sum % N) {
        return -1;
    }
    Sum /= N;
    sort(arr, arr + N);
    int ans = 0, i = 0;
    while (i < N) {
        int j = i + 1;
        while (j < N && arr[j] <= Sum) {
            j++;
        }
        if (j == N) {
            break;
        }
        ans += j - i;
        arr[i] += j - i;
        arr[j] -= j - i;
        i++;
    }
    return ans;
}
  
int main() {
    int arr[] = { 5, 4, 1, 10 };
    int N = sizeof(arr) / sizeof(int);
    cout << find(arr, N); // Output: 5
    return 0;
}




// Java implementation of a function to
// find the minimum number of moves required
// to make all elements of an array equal
import java.util.Arrays;
 
public class Main {
 
 
// Function to find the minimum number of moves required
// to make all elements of an array equal
static int find(int arr[], int N) {
 
    // Calculate the sum of all the elements of the array
    int Sum = 0;
    for (int i = 0; i < N; i++) {
        Sum += arr[i];
    }
 
    // If the sum is not divisible by N, we cannot make all
    // elements equal by adding or subtracting from each other.
    // Hence, return -1.
    if (Sum % N != 0) {
        return -1;
    }
 
    // Calculate the target sum by dividing the sum of
    // all elements by N.
    int targetSum = Sum / N;
 
    // Sort the array in non-decreasing order
    Arrays.sort(arr);
 
    int ans = 0, i = 0;
    while (i < N) {
        // Find the index j of the first element in the array
        // that is greater than the target sum.
        int j = i + 1;
        while (j < N && arr[j] <= targetSum) {
            j++;
        }
 
        // If j equals N, it means that all the remaining
        // elements in the array are less than or equal to
        // the target sum, and hence, we cannot make them
        // equal to the target sum by adding or subtracting
        // from each other. Therefore, break out of the loop.
        if (j == N) {
            break;
        }
 
        // Calculate the number of moves required to make
        // elements arr[i] to arr[j-1] equal to the target sum.
        ans += j - i;
        arr[i] += j - i;
        arr[j] -= j - i;
        i++;
    }
 
    return ans;
}
 
public static void main(String[] args) {
    int arr[] = { 5, 4, 1, 10 };
    int N = arr.length;
    System.out.println(find(arr, N)); // Output: 5
}
 
}




def find(arr, N):
    Sum = sum(arr)
    if Sum % N:
        return -1
    Sum //= N
    arr.sort()
    ans, i = 0, 0
    while i < N:
        j = i + 1
        while j < N and arr[j] <= Sum:
            j += 1
        if j == N:
            break
        ans += j - i
        arr[i:i+j-i] = [arr[i] + j - i] * (j - i)
        arr[j] -= j - i
        i += 1
    return ans
 
arr = [5, 4, 1, 10]
N = len(arr)
print(find(arr, N)) # Output: 5




// Javascript implementation of a function to
// find the minimum number of moves required
// to make all elements of an array equal
 
// Function to find the minimum number of moves required
// to make all elements of an array equal
function find(arr, N) {
 
    // Calculate the sum of all the elements of the array
    let Sum = 0;
    for (let i = 0; i < N; i++) {
        Sum += arr[i];
    }
     
     // If the sum is not divisible by N, we cannot make all
    // elements equal by adding or subtracting from each other.
    // Hence, return -1.
    if (Sum % N) {
        return -1;
    }
     // Calculate the target sum by dividing the sum of
    // all elements by N.
    Sum /= N;
     
    // Sort the array in non-decreasing order
    arr.sort((a, b) => a - b);
    let ans = 0, i = 0;
    while (i < N) {
         // Find the index j of the first element in the array
        // that is greater than the target sum.
        let j = i + 1;
        while (j < N && arr[j] <= Sum) {
            j++;
        }
         
         // If j equals N, it means that all the remaining
        // elements in the array are less than or equal to
        // the target sum, and hence, we cannot make them
        // equal to the target sum by adding or subtracting
        // from each other. Therefore, break out of the loop.
        if (j == N) {
            break;
        }
         
         // Calculate the number of moves required to make
        // elements arr[i] to arr[j-1] equal to the target sum.
        ans += j - i;
        arr[i] += j - i;
        arr[j] -= j - i;
        i++;
    }
    return ans;
}
 
let arr = [5, 4, 1, 10];
let N = arr.length;
console.log(find(arr, N)); // Output: 5




using System;
using System.Collections.Generic;
 
class Gfg{
     
    static int find(int[] arr, int N) {
        int Sum = 0, i=0;
         
        for ( i = 0; i < N; i++) {
            Sum += arr[i];
        }
        if (Sum % N !=0) {
            return -1;
        }
        Sum /= N;
        Array.Sort(arr);
        int ans = 0;
        i = 0;
        while (i < N) {
            int j = i + 1;
            while (j < N && arr[j] <= Sum) {
                j++;
            }
            if (j == N) {
                break;
            }
            ans += j - i;
            arr[i] += j - i;
            arr[j] -= j - i;
            i++;
        }
        return ans;
    }
      
    public static void Main(String[] args)
    {
        int[] arr = { 5, 4, 1, 10 };
        int N = arr.Length;
        Console.Write(find(arr, N)); // Output: 5
    }
}

Output
5

Time Complexity: O(N), where N is the size of the input array

Auxiliary Space: O(1)


Article Tags :