Minimize increment or increment and decrement of Pair to make all Array elements equal
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:
- Choose an element of the array and increase it by 1.
- 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++
#include <bits/stdc++.h>
#define ll long long
#define mod 1000000007
using namespace std;
int findMinOperations(vector< int > a, int n)
{
ll avg = 0;
sort(a.begin(), a.end());
for ( int i : a) {
avg += i;
}
avg = avg % n == 0 ? avg / n : avg / n + 1;
int i = 0, j = n - 1;
int ans = 0;
while (i <= j) {
if (a[i] < avg) {
int incrementNeeded = avg - a[i];
int k = incrementNeeded;
a[i] = 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--;
}
ans += incrementNeeded;
}
i++;
}
return ans;
}
int main()
{
vector< int > A;
A = { 1, 2, 3, 4 };
int N = A.size();
cout << findMinOperations(A, N);
return 0;
}
|
Java
import java.util.*;
public class GFG {
static int findMinOperations( int [] a, int n)
{
long avg = 0 ;
Arrays.sort(a);
for ( int x = 0 ; x < a.length; x++) {
avg += a[x];
}
avg = avg % n == 0 ? avg / n : avg / n + 1 ;
int i = 0 , j = n - 1 ;
int ans = 0 ;
while (i <= j) {
if (a[i] < avg) {
int incrementNeeded = ( int )avg - a[i];
int k = incrementNeeded;
a[i] = ( int )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--;
}
ans += incrementNeeded;
}
i++;
}
return ans;
}
public static void main(String args[])
{
int [] A = { 1 , 2 , 3 , 4 };
int N = A.length;
System.out.println(findMinOperations(A, N));
}
}
|
Python3
def findMinOperations(a, n):
avg = 0
a = sorted (a)
avg = sum (a)
if avg % n = = 0 :
avg = avg / / n
else :
avg = avg / / n + 1
i = 0
j = n - 1
ans = 0
while i < = j:
if a[i] < avg:
incrementNeeded = avg - a[i]
k = incrementNeeded
a[i] = 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
ans + = incrementNeeded
i + = 1
return ans
if __name__ = = '__main__' :
a = [ 1 , 2 , 3 , 4 ]
n = len (a)
print (findMinOperations(a, n))
|
C#
using System;
class GFG
{
static int findMinOperations( int []a, int n)
{
long avg = 0;
Array.Sort(a);
for ( int x = 0; x < a.Length; x++) {
avg += a[x];
}
avg = avg % n == 0 ? avg / n : avg / n + 1;
int i = 0, j = n - 1;
int ans = 0;
while (i <= j) {
if (a[i] < avg) {
int incrementNeeded = ( int )avg - a[i];
int k = incrementNeeded;
a[i] = ( int )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--;
}
ans += incrementNeeded;
}
i++;
}
return ans;
}
public static void Main()
{
int []A = { 1, 2, 3, 4 };
int N = A.Length;
Console.Write(findMinOperations(A, N));
}
}
|
Javascript
<script>
let mod = 1000000007
function findMinOperations(a, n) {
let avg = 0;
a.sort()
for (let i of a) {
avg += i;
}
avg = avg % n == 0 ? Math.floor(avg / n) : Math.floor(avg / n) + 1;
let i = 0, j = n - 1;
let ans = 0;
while (i <= j) {
if (a[i] < avg) {
let incrementNeeded = avg - a[i];
let k = incrementNeeded;
a[i] = 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--;
}
ans += incrementNeeded;
}
i++;
}
return ans;
}
let A;
A = [1, 2, 3, 4];
let N = A.length;
document.write(findMinOperations(A, N));
</script>
|
Time Complexity: O(N*logN) as it is using sorting
Auxiliary Space: O(1)
Last Updated :
07 Oct, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...