Open In App

Minimize increment or increment and decrement of Pair to make all Array elements equal

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of size N, the task is to minimize the number of steps to make all the array elements equal by performing the following operations:

  1. Choose an element of the array and increase it by 1.
  2. Select two elements simultaneously (arr[i], arr[j]) increase arr[i] by 1 and decrease arr[j] by 1.

Examples:

Input: arr = [4, 2, 4, 6]
Output: 2
Explanation: Do operation 2 on element 2 and 6 of the array. 
Hence increasing 2 by 2 and decreasing 6 by 2 makes all the elements of the array equal.

Input: arr = [1, 2, 3, 4]
Output: 3
Explanation: Increase 1 by 1 once. arr[] = {2, 2, 3, 4}.
Then increase 1 by 1 and decrease 4 by 1 in one step. arr[] = {3, 2, 3, 3}
Increase 2 by 1. arr[] = {3, 3, 3, 3}. So total operations = 3.

Approach: This problem can be solved using the greedy approach based on the following idea:

To minimize the number of steps make all of them equal to the ceil(average) of all array elements. To do this simultaneously increase the less elements and decrement the greater elements as long as possible and then increment the lesser elements only.

Follow the steps mentioned below to solve the problem:

  • Sort the array.
  • Find out the ceil of the average of the array (say avg).
  • Now traverse the array from i = 0 to N-1:
    • Whenever you find any element smaller than avg.
      • Traverse from the back end of the array and deduce the elements which are greater than avg.
      • Finally, add avg-a[i] to the answer.
  • Return the answer.

Below is the implementation of the above approach:

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
#define ll long long
#define mod 1000000007
using namespace std;
 
// function to find the minimum operations
// to make the array elements same
int findMinOperations(vector<int> a, int n)
{
    ll avg = 0;
 
    // Sorting the array
    sort(a.begin(), a.end());
    for (int i : a) {
        avg += i;
    }
 
    // Finding out the average
 
    avg = avg % n == 0 ? avg / n : avg / n + 1;
    int i = 0, j = n - 1;
    int ans = 0;
 
    // Traversing the array
    while (i <= j) {
 
        // If current element is less than avg
        if (a[i] < avg) {
 
            // Total increments needed
            int incrementNeeded = avg - a[i];
            int k = incrementNeeded;
            a[i] = avg;
 
            // Traversing in the right side
            // of the array to find elements
            // which needs to be deduced to avg
            while (j > i && k > 0
                   && a[j] > avg) {
                int decrementNeeded
                    = a[j] - avg;
                if (k <= decrementNeeded) {
                    k -= decrementNeeded;
                }
                else {
                    a[j] -= k;
                    k = 0;
                }
                j--;
            }
 
            // Adding increments
            // needed to ans
            ans += incrementNeeded;
        }
        i++;
    }
    return ans;
}
 
// Driver Code
int main()
{
    vector<int> A;
    A = { 1, 2, 3, 4 };
    int N = A.size();
    cout << findMinOperations(A, N);
    return 0;
}


Java




// Java code to implement the approach
import java.util.*;
public class GFG {
 
  // function to find the minimum operations
  // to make the array elements same
  static int findMinOperations(int[] a, int n)
  {
    long avg = 0;
 
    // Sorting the array
    Arrays.sort(a);
    for (int x = 0; x < a.length; x++) {
      avg += a[x];
    }
 
    // Finding out the average
    avg = avg % n == 0 ? avg / n : avg / n + 1;
    int i = 0, j = n - 1;
    int ans = 0;
 
    // Traversing the array
    while (i <= j) {
 
      // If current element is less than avg
      if (a[i] < avg) {
 
        // Total increments needed
        int incrementNeeded = (int)avg - a[i];
        int k = incrementNeeded;
        a[i] = (int)avg;
 
        // Traversing in the right side
        // of the array to find elements
        // which needs to be deduced to avg
        while (j > i && k > 0 && a[j] > avg) {
          int decrementNeeded = a[j] - (int)avg;
          if (k <= decrementNeeded) {
            k -= decrementNeeded;
          }
          else {
            a[j] -= k;
            k = 0;
          }
          j--;
        }
 
        // Adding increments
        // needed to ans
        ans += incrementNeeded;
      }
      i++;
    }
    return ans;
  }
 
  // Driver Code
  public static void main(String args[])
  {
    int[] A = { 1, 2, 3, 4 };
    int N = A.length;
    System.out.println(findMinOperations(A, N));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Python3




# Python code to implement the approach
 
# function to find the minimum operations
# to make the array elements same
def findMinOperations(a, n):
    avg = 0
 
    # sorting the array
    a = sorted(a)
    avg = sum(a)
    # finding the average of the array
    if avg % n == 0:
        avg = avg//n
    else:
        avg = avg//n + 1
    i = 0
    j = n-1
    ans = 0
 
    # traverse the array
    while i <= j:
 
        # if current element is less than avg
        if a[i] < avg:
 
            # total increment needed
            incrementNeeded = avg - a[i]
            k = incrementNeeded
            a[i] = avg
 
            # Traversing in the right side
            # of the array to find elements
            # which needs to be deducted to avg
            while j > i and k > 0 and a[j] > avg:
                decrementNeeded = a[j] - avg
                if k <= decrementNeeded:
                    k -= decrementNeeded
                else:
                    a[j] -= k
                    k = 0
 
                j -= 1
            # Adding increments
            # needed to ans
            ans += incrementNeeded
        i += 1
    return ans
 
 
# Driver code
if __name__ == '__main__':
    a = [1, 2, 3, 4]
    n = len(a)
    print(findMinOperations(a, n))
 
    # This code is contributed by Amnindersingg1414.


C#




// C# code to implement the approach
using System;
class GFG
{
 
  // function to find the minimum operations
  // to make the array elements same
  static int findMinOperations(int []a, int n)
  {
    long avg = 0;
 
    // Sorting the array
    Array.Sort(a);
    for (int x = 0; x < a.Length; x++) {
      avg += a[x];
    }
 
    // Finding out the average
    avg = avg % n == 0 ? avg / n : avg / n + 1;
    int i = 0, j = n - 1;
    int ans = 0;
 
    // Traversing the array
    while (i <= j) {
 
      // If current element is less than avg
      if (a[i] < avg) {
 
        // Total increments needed
        int incrementNeeded = (int)avg - a[i];
        int k = incrementNeeded;
        a[i] = (int)avg;
 
        // Traversing in the right side
        // of the array to find elements
        // which needs to be deduced to avg
        while (j > i && k > 0
               && a[j] > avg) {
          int decrementNeeded
            = a[j] - (int)avg;
          if (k <= decrementNeeded) {
            k -= decrementNeeded;
          }
          else {
            a[j] -= k;
            k = 0;
          }
          j--;
        }
 
        // Adding increments
        // needed to ans
        ans += incrementNeeded;
      }
      i++;
    }
    return ans;
  }
 
  // Driver Code
  public static void Main()
  {
    int []A = { 1, 2, 3, 4 };
    int N = A.Length;
    Console.Write(findMinOperations(A, N));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript




<script>
        // JavaScript code for the above approach
        let mod = 1000000007
 
        // function to find the minimum operations
        // to make the array elements same
        function findMinOperations(a, n) {
            let avg = 0;
 
            // Sorting the array
            a.sort()
            for (let i of a) {
                avg += i;
            }
 
            // Finding out the average
            avg = avg % n == 0 ? Math.floor(avg / n) : Math.floor(avg / n) + 1;
            let i = 0, j = n - 1;
            let ans = 0;
 
            // Traversing the array
            while (i <= j) {
 
                // If current element is less than avg
                if (a[i] < avg) {
 
                    // Total increments needed
                    let incrementNeeded = avg - a[i];
                    let k = incrementNeeded;
                    a[i] = avg;
 
                    // Traversing in the right side
                    // of the array to find elements
                    // which needs to be deduced to avg
                    while (j > i && k > 0
                        && a[j] > avg) {
                        let decrementNeeded
                            = a[j] - avg;
                        if (k <= decrementNeeded) {
                            k -= decrementNeeded;
                        }
                        else {
                            a[j] -= k;
                            k = 0;
                        }
                        j--;
                    }
 
                    // Adding increments
                    // needed to ans
                    ans += incrementNeeded;
                }
                i++;
            }
            return ans;
        }
 
        // Driver Code
        let A;
        A = [1, 2, 3, 4];
        let N = A.length;
        document.write(findMinOperations(A, N));
 
   // This code is contributed by Potta Lokesh
 
    </script>


 
 

Output

3

 

Time Complexity: O(N*logN) as it is using sorting
Auxiliary Space: O(1)



Last Updated : 07 Oct, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads