Make all array elements equal with minimum cost

22 Jun, 2022
Given an array which contains integer values, we need to make all values of this array equal to some integer value with minimum cost where the cost of changing an array value x to y is abs(x-y). 
Examples : 
Input  : arr[] = [1, 100, 101]
Output : 100
We can change all its values to 100 with minimum cost,
|1 - 100| + |100 - 100| + |101 - 100| = 100

Input  : arr[] = [4, 6]
Output : 2
We can change all its values to 5 with minimum cost,
|4 - 5| + |5 - 6| = 2
This problem can be solved by observing the cost while changing the target equal value, i.e. we will see the change in cost when target equal value is changed. It can be observed that, as we increase the target equal value the total cost decreases up to a limit and then starts increasing i.e. the cost graph with respect to target equal value is of U-shape and as cost graph is in U-shape, the ternary search can be applied to this search space and our goal is to get that bottom most point of the curve which will represent the smallest cost. We will make smallest and largest value of the array as the limit of our search space and then we will keep skipping 1/3 part of the search space until we reach to the bottom most point of our U-curve. 
Please see below code for better understanding.
C++
Java
Python3
C#
PHP
Javascript
// C++ program to find minimum cost to// make all elements equal#include <bits/stdc++.h>using namespace std; // Utility method to compute cost, when// all values of array are made equal to Xint computeCost(int arr[], int N, int X){    int cost = 0;    for (int i = 0; i < N; i++)        cost += abs(arr[i] - X);    return cost;} // Method to find minimum cost to make all// elements equalint minCostToMakeElementEqual(int arr[], int N){    int low, high;    low = high = arr[0];     // setting limits for ternary search by    // smallest and largest element    for (int i = 0; i < N; i++) {        if (low > arr[i])            low = arr[i];        if (high < arr[i])            high = arr[i];    }     /* loop until difference between low and high       become less than 3, because after that       mid1 and mid2 will start repeating    */    while ((high - low) > 2) {         // mid1 and mid2 are representative array        // equal values of search space        int mid1 = low + (high - low) / 3;        int mid2 = high - (high - low) / 3;         int cost1 = computeCost(arr, N, mid1);        int cost2 = computeCost(arr, N, mid2);         // if mid2 point gives more total cost,        // skip third part        if (cost1 < cost2)            high = mid2;         // if mid1 point gives more total cost,        // skip first part        else            low = mid1;    }     // computeCost gets optimum cost by sending    // average of low and high as X    return computeCost(arr, N, (low + high) / 2);} // Driver code to test above methodint main(){    int arr[] = { 1, 100, 101 };    int N = sizeof(arr) / sizeof(int);    cout << minCostToMakeElementEqual(arr, N);    return 0;}
// JAVA Code for Make all array elements// equal with minimum costclass GFG {     // Utility method to compute cost, when    // all values of array are made equal to X    public static int computeCost(int arr[], int N,                                  int X)    {        int cost = 0;        for (int i = 0; i < N; i++)            cost += Math.abs(arr[i] - X);        return cost;    }     // Method to find minimum cost to make all    // elements equal    public static int minCostToMakeElementEqual(int arr[],                                                int N)    {        int low, high;        low = high = arr[0];         // setting limits for ternary search by        // smallest and largest element        for (int i = 0; i < N; i++) {            if (low > arr[i])                low = arr[i];            if (high < arr[i])                high = arr[i];        }         /* loop until difference between low and high           become less than 3, because after that           mid1 and mid2 will start repeating        */        while ((high - low) > 2) {            // mid1 and mid2 are representative array            // equal values of search space            int mid1 = low + (high - low) / 3;            int mid2 = high - (high - low) / 3;             int cost1 = computeCost(arr, N, mid1);            int cost2 = computeCost(arr, N, mid2);             // if mid2 point gives more total cost,            // skip third part            if (cost1 < cost2)                high = mid2;             // if mid1 point gives more total cost,            // skip first part            else                low = mid1;        }         // computeCost gets optimum cost by sending        // average of low and high as X        return computeCost(arr, N, (low + high) / 2);    }     /* Driver program to test above function */    public static void main(String[] args)    {        int arr[] = { 1, 100, 101 };        int N = arr.length;        System.out.println(minCostToMakeElementEqual(arr, N));    }}// This code is contributed by Arnav Kr. Mandal.
# Python3 program to find minimum # cost to make all elements equal # Utility method to compute cost, when# all values of array are made equal to Xdef computeCost(arr, N, X):     cost = 0    for i in range(N):        cost += abs(arr[i] - X)    return cost  # Method to find minimum cost to# make all elements equaldef minCostToMakeElementEqual(arr, N):     low = high = arr[0]     # Setting limits for ternary search    # by smallest and largest element    for i in range(N):             if (low > arr[i]): low = arr[i]        if (high < arr[i]): high = arr[i]      # loop until difference between low and    # high become less than 3, because after    # that mid1 and mid2 will start repeating    while ((high - low) > 2):             # mid1 and mid2 are representative        # array equal values of search space        mid1 = low + (high - low) // 3        mid2 = high - (high - low) // 3         cost1 = computeCost(arr, N, mid1)        cost2 = computeCost(arr, N, mid2)         # if mid2 point gives more total        # cost, skip third part        if (cost1 < cost2):            high = mid2         # if mid1 point gives more total        # cost, skip first part        else:            low = mid1          # computeCost gets optimum cost by    # sending average of low and high as X    return computeCost(arr, N, (low + high) // 2) # Driver codearr = [1, 100, 101]N = len(arr)print(minCostToMakeElementEqual(arr, N)) # This code is contributed by Anant Agarwal.
// C# Code to Make all array elements// equal with minimum costusing System; class GFG {     // Utility method to compute cost, when    // all values of array are made equal to X    public static int computeCost(int[] arr, int N,                                             int X)    {        int cost = 0;        for (int i = 0; i < N; i++)            cost += Math.Abs(arr[i] - X);        return cost;    }     // Method to find minimum cost to    // make all elements equal    public static int minCostToMakeElementEqual(int[] arr,                                                    int N)    {        int low, high;        low = high = arr[0];         // setting limits for ternary search by        // smallest and largest element        for (int i = 0; i < N; i++) {            if (low > arr[i])                low = arr[i];            if (high < arr[i])                high = arr[i];        }         /* loop until difference between low and high        become less than 3, because after that        mid1 and mid2 will start repeating        */        while ((high - low) > 2) {                         // mid1 and mid2 are representative array            // equal values of search space            int mid1 = low + (high - low) / 3;            int mid2 = high - (high - low) / 3;             int cost1 = computeCost(arr, N, mid1);            int cost2 = computeCost(arr, N, mid2);             // if mid2 point gives more total cost,            // skip third part            if (cost1 < cost2)                high = mid2;             // if mid1 point gives more total cost,            // skip first part            else                low = mid1;        }         // computeCost gets optimum cost by sending        // average of low and high as X        return computeCost(arr, N, (low + high) / 2);    }     /* Driver program to test above function */    public static void Main()    {        int[] arr = { 1, 100, 101 };        int N = arr.Length;        Console.Write(minCostToMakeElementEqual(arr, N));    }} // This code is contributed by nitin mittal
<?php// PHP program to find minimum cost// to make all elements equal // Utility method to compute cost,// when all values of array are// made equal to Xfunction computeCost($arr, $N, $X){    $cost = 0;    for ($i = 0; $i < $N; $i++)        $cost += abs($arr[$i] - $X);    return $cost;} // Method to find minimum cost// to make all elements equalfunction minCostToMakeElementEqual($arr, $N){    $low; $high;    $low = $high = $arr[0];     // setting limits for ternary    // search by smallest and    // largest element    for ($i = 0; $i < $N; $i++)    {        if ($low > $arr[$i])            $low = $arr[$i];        if ($high < $arr[$i])            $high = $arr[$i];    }     /* loop until difference between    low and high become less than 3,    because after that mid1 and mid2    will start repeating */    while (($high - $low) > 2)    {        // mid1 and mid2 are representative        // array equal values of search space        $mid1 = $low + (floor($high - $low) / 3);        $mid2 = $high - ($high - $low) / 3;         $cost1 = computeCost($arr, $N, $mid1);        $cost2 = computeCost($arr, $N, $mid2);         // if mid2 point gives more total        // cost, skip third part        if ($cost1 < $cost2)            $high = $mid2;         // if mid1 point gives more        // total cost, skip first part        else            $low = $mid1;    }     // computeCost gets optimum cost by    // sending average of low and high as X    return computeCost($arr, $N, ($low +                                  $high) / 2);} // Driver Code$arr = array( 1, 100, 101 );$N = sizeof($arr) / sizeof($arr[0]);echo minCostToMakeElementEqual($arr, $N); // This code is contributed by nitin mittal.?>
<script> // Javascript program to find minimum cost to// make all elements equal       // Utility method to compute cost, when    // all values of array are made equal to X    function computeCost(arr, N, X)    {        let cost = 0;        for (let i = 0; i < N; i++)            cost += Math.abs(arr[i] - X);        return cost;    }     // Method to find minimum cost to make all    // elements equal    function minCostToMakeElementEqual(arr, N)    {        let low, high;        low = high = arr[0];         // setting limits for ternary search by        // smallest and largest element        for (let i = 0; i < N; i++) {            if (low > arr[i])                low = arr[i];            if (high < arr[i])                high = arr[i];        }         /* loop until difference between low and high           become less than 3, because after that           mid1 and mid2 will start repeating        */        while ((high - low) > 2) {            // mid1 and mid2 are representative array            // equal values of search space            let mid1 = low + (high - low) / 3;            let mid2 = high - (high - low) / 3;             let cost1 = computeCost(arr, N, mid1);            let cost2 = computeCost(arr, N, mid2);             // if mid2 point gives more total cost,            // skip third part            if (cost1 < cost2)                high = mid2;             // if mid1 point gives more total cost,            // skip first part            else                low = mid1;        }         // computeCost gets optimum cost by sending        // average of low and high as X        return Math.round(computeCost(arr, N, (low + high) / 2));    }  // Driver Code         let arr = [ 1, 100, 101 ];    let N = arr.length;    document.write(minCostToMakeElementEqual(arr, N));         </script>
100
 
Time Complexity: O(NlogN)Auxiliary Space: O(1)
Alternate Solution Think geometrically. Assume that array elements are co-ordinates on x axis. The problem reduces to finding another co-ordinate such that the sum of distances between this choice and other co-ordinates is minimized. Observe that: If number of coordinates are odd then y = middle element. If even then y is any number in between middle 2 co-ordinates. Say Input = [a, b, c, d]. Output is any number between b and c including both. Hence the cost is sum which can be computed easily now that we have chosen y. sum|(y-ai)| for all i. 
It is really easy to code it. 
C++
Java
Python3
C#
Javascript
#include <bits/stdc++.h>using namespace std; // This function assumes that a[] is// sorted. If a[] is not sorted, we need// to sort it first.int minCostToMakeElementEqual(int a[], int n){     // If there are odd elements, we choose    // middle element    int y;    if (n % 2 == 1)        y = a[n / 2];     // If there are even elements, then we choose    // the average of middle two.    else        y = (a[n / 2] + a[(n - 2) / 2]) / 2;     // After deciding the final value, find the    // result.    int s = 0;    for(int i = 0; i < n; i++)        s += abs(a[i] - y);             return s;} // Driver codeint main(){    int a[] = { 1, 100, 101 };    int n = sizeof(a) / sizeof(a[0]);         cout << (minCostToMakeElementEqual(a, n));} // This code is contributed by chitranayal
import java.io.*;import java.util.*; class GFG{ // This function assumes that a[] is// sorted. If a[] is not sorted, we need// to sort it first.   public static int minCostToMakeElementEqual(int a[],                                            int n){         // If there are odd elements, we choose    // middle element    int y;         if (n % 2 == 1)        y = a[n / 2];         // If there are even elements, then we    // choose the average of middle two.    else        y = (a[n / 2] + a[(n - 2) / 2]) / 2;         // After deciding the final value,    // find the result.    int s = 0;         for(int i = 0; i < n; i++)        s += Math.abs(a[i] - y);         return s;} // Driver codepublic static void main (String[] args){    int a[] = { 1, 100, 101 };    int n = a.length;         System.out.println(minCostToMakeElementEqual(a, n));}} // This code is contributed by parascoding
# This function assumes that a[] is# sorted. If a[] is not sorted, we need# to sort it first.def minCostToMakeElementEqual(a):    l = len(a)     # If there are odd elements, we choose    # middle element    if (l%2 == 1):        y = a[l//2]     # If there are even elements, then we choose    # the average of middle two.    else:        y = (a[l//2] + a[(l-2)//2])//2     # After deciding the final value, find the    # result.    s = 0    for i in range(l):        s += abs(a[i]-y)    return s # Driver codea = [1, 100, 101]print(minCostToMakeElementEqual(a))
using System;using System.Collections.Generic; class GFG{     // This function assumes that a[] is// sorted. If a[] is not sorted, we need// to sort it first.   static int minCostToMakeElementEqual(int[] a,                                     int n){         // If there are odd elements, we choose    // middle element    int y;          if (n % 2 == 1)        y = a[n / 2];          // If there are even elements, then we    // choose the average of middle two.    else        y = (a[n / 2] + a[(n - 2) / 2]) / 2;          // After deciding the final value,    // find the result.    int s = 0;          for(int i = 0; i < n; i++)        s += Math.Abs(a[i] - y);          return s;} // Driver codestatic void Main(){    int[] a = { 1, 100, 101 };    int n = a.Length;          Console.WriteLine(        minCostToMakeElementEqual(a, n));}} // This code is contributed by divyeshrabadiya07
<script>  // This function assumes that a[] is// sorted. If a[] is not sorted, we need// to sort it first.function minCostToMakeElementEqual( a, n){     // If there are odd elements, we choose    // middle element    let y;    if (n % 2 == 1)        y = a[Math.trunc(n / 2)];     // If there are even elements, then we choose    // the average of middle two.    else        y = Math.trunc((a[n / 2] + a[(n - 2) / 2]) / 2);     // After deciding the final value, find the    // result.    let s = 0;    for(let i = 0; i < n; i++)        s += Math.abs(a[i] - y);             return s;}           // Driver program         let a = [ 1, 100, 101 ];    let n = a.length;         document.write(minCostToMakeElementEqual(a, n));      </script>
100
Time Complexity: O(n)Auxiliary Space: O(1)
This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
nitin mittal
dhruvprakash1994saraswathi
ukasp
parascoding
divyeshrabadiya07
souravghosh0416
jana_sayantan
susobhanakhuli
Arrays
Searching
Arrays
Searching
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Multidimensional Arrays in Java
Linear Search
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Introduction to Arrays
K'th Smallest/Largest Element in Unsorted Array | Set 1
Binary Search
Linear Search
K'th Smallest/Largest Element in Unsorted Array | Set 1
Search an element in a sorted and rotated array
Find the Missing Number