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.
- Whenever you find any element smaller than avg.
- 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>
3
Time Complexity: O(N*logN) as it is using sorting
Auxiliary Space: O(1)
Please Login to comment...