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.
- Whenever you find any element smaller than avg.
- Return the answer.
Below is the implementation of the above approach:
// 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 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. |
# 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# 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. |
<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>
|
3
Time Complexity: O(N*logN) as it is using sorting
Auxiliary Space: O(1)