Open In App

Minimum cost to make all elements with same frequency equal

Last Updated : 04 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of integers, the task is to find the minimum cost for making all the integers that have the same frequency equal. By performing one operation you can either increase the current integer by 1 or decrease it by 1.

Examples:

Input: arr[] = {1, 2, 3, 2, 6, 5, 6}
Output: 12
Explanation: 1, 3, and 5 have the same frequency i.e. 1, so for making them equal it will cost 4 operations, 2 and 6 have the same frequency i.e. 2, so for making them equal it will cost 8 operations. Total will be 8 + 4 = 12 operations .

Input: arr[] = {4, 7, 1, 13, 4, 1, 1, 4}
Output: 15
Explanation: 1 and 4 have the same frequency i.e. 3, so making them equal it will cost 9 operations. 7 and 13 have the same frequency i.e. 1, so for making them equal it will cost 6 operations. Total will be 9 + 6 = 15 operations.

Approach: To solve the problem follow the below idea:

The idea is to find the frequency of all elements first and then group all elements that have the same frequency after that find the minimum cost to make all values in every group equal then return this minimum cost.

This can be done by following the below mentioned steps :

  • Initialize a map mp to store frequency of array elements, Iterate over the given array and store the frequency of its elements.
  • Initialize another map data to store array elements which have same frequency. Iterate over the mp map and for every iteration push the value into data map with its frequency .By the end of this traversal, data will have all frequency along with elements which have these frequencies.
  • Now Initialize a variable sum with 0 and Iterate over the data map and check if number of elements which are associated with current frequency are more than 1 then find the minimum cost to make them equal by passing this vector of elements named value to minimumCost function .Multiple the received value with frequency associated with it then add it to sum variable. After completing the iteration return sum.
  • In minimumCost function, find the average of all array elements then initialize a variable with 0 for storing absolute difference then iterate over the vector and find the absolute difference between average value and current array element and add it to the sum variable . After completing the traversal return it.

Below Code is the implementation of the above approach in C++.

C++




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
int minimumCost(vector<int> values)
{
    // Function for finding minimum cost to
    // make all the elements equal
    int sum = 0;
    for (int i = 0; i < values.size(); i++) {
 
        // For finding sum of all elements
        sum += values[i];
    }
 
    // For calculating
    // average
    int avg = sum / values.size();
 
    // For storing the minimum cost
    int cost = 0;
    for (int i = 0; i < values.size(); i++) {
 
        // Adding absolute difference of every
        // element with the avergae value
        cost += abs(values[i] - avg);
    }
 
    // Returning the minimum cost
    return cost;
}
 
int minCost(vector<int> arr)
{
 
    // map for storing the frequency
    // of all elements
    map<int, int> mp;
    for (int i = 0; i < arr.size(); i++) {
        mp[arr[i]]++;
    }
 
    // map for storing values associated
    // with a specific frequency
    map<int, vector<int> > data;
    for (auto it = mp.begin(); it != mp.end(); it++) {
        data[it->second].push_back(it->first);
    }
 
    // Variable for calculating total
    // cost
    int totalCost = 0;
 
    // Iterating over the data map for
    // calculating minimum cost
    for (auto it = data.begin(); it != data.end(); it++) {
 
        // Storing the list of elements
        // which have same frequency in a
        // vector
        vector<int> values = it->second;
 
        // If number of elements which have same
        // frequency are more than 1 then for
        // making them equal we will pass them to
        // minimumCost function
        if (values.size() > 1) {
            totalCost += (it->first) * minimumCost(values);
        }
    }
 
    // Returning the total calculated cost
    return totalCost;
}
 
// Drivers code
int main()
{
    std::vector<int> arr = { 1, 2, 3, 5, 3 };
 
    // Function call
    cout << minCost(arr);
    return 0;
}


Java




import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class Main {
    public static int minimumCost(List<Integer> values) {
        // Function for finding minimum cost to make all the elements equal
        int sum = 0;
        for (int value : values) {
            // For finding the sum of all elements
            sum += value;
        }
 
        // For calculating the average
        int avg = sum / values.size();
 
        // For storing the minimum cost
        int cost = 0;
        for (int value : values) {
            // Adding the absolute difference of every element with the average value
            cost += Math.abs(value - avg);
        }
 
        // Returning the minimum cost
        return cost;
    }
 
    public static int minCost(List<Integer> arr) {
        // Map for storing the frequency of all elements
        Map<Integer, Integer> mp = new HashMap<>();
        for (int value : arr) {
            mp.put(value, mp.getOrDefault(value, 0) + 1);
        }
 
        // Map for storing values associated with a specific frequency
        Map<Integer, List<Integer>> data = new HashMap<>();
        for (Map.Entry<Integer, Integer> entry : mp.entrySet()) {
            int frequency = entry.getValue();
            int value = entry.getKey();
            data.computeIfAbsent(frequency, k -> new ArrayList<>()).add(value);
        }
 
        // Variable for calculating total cost
        int totalCost = 0;
 
        // Iterating over the data map for calculating minimum cost
        for (Map.Entry<Integer, List<Integer>> entry : data.entrySet()) {
            int frequency = entry.getKey();
            List<Integer> values = entry.getValue();
 
            // If the number of elements with the same frequency is more than 1,
            // pass them to the minimumCost function to make them equal
            if (values.size() > 1) {
                totalCost += frequency * minimumCost(values);
            }
        }
 
        // Returning the total calculated cost
        return totalCost;
    }
 
    // Driver code
    public static void main(String[] args) {
        List<Integer> arr = new ArrayList<>();
        arr.add(1);
        arr.add(2);
        arr.add(3);
        arr.add(5);
        arr.add(3);
 
        // Function call
        System.out.println(minCost(arr));
    }
}


Python3




from collections import defaultdict
 
def minimum_cost(values):
    # Calculate sum of all elements
    total_sum = sum(values)
     
    # Calculate average
    average = total_sum // len(values)
     
    # Calculate cost by summing absolute differences from average
    cost = sum(abs(val - average) for val in values)
     
    return cost
 
def min_cost(arr):
    # Dictionary to store frequency of elements
    freq_map = defaultdict(int)
    for val in arr:
        freq_map[val] += 1
 
    # Dictionary to store values associated with a specific frequency
    data = defaultdict(list)
    for key, value in freq_map.items():
        data[value].append(key)
 
    # Variable for calculating total cost
    total_cost = 0
 
    # Calculate minimum cost
    for freq, values in data.items():
        # If elements with the same frequency are more than 1
        # calculate cost to make them equal and add to total cost
        if len(values) > 1:
            total_cost += freq * minimum_cost(values)
     
    return total_cost
 
# Driver code
arr = [1, 2, 3, 5, 3]
 
# Function call
print(min_cost(arr))


C#




// C# code for the above approach
using System;
using System.Collections.Generic;
using System.Linq;
 
class GFG
{
    static int MinimumCost(List<int> values)
    {
        // Function for finding minimum cost to
        // make all the elements equal
        int sum = 0;
        foreach (int value in values)
        {
            // For finding sum of all elements
            sum += value;
        }
 
        // For calculating average
        int avg = sum / values.Count;
 
        // For storing the minimum cost
        int cost = 0;
        foreach (int value in values)
        {
            // Adding absolute difference of every
            // element with the average value
            cost += Math.Abs(value - avg);
        }
 
        // Returning the minimum cost
        return cost;
    }
 
    static int MinCost(List<int> arr)
    {
        // Dictionary for storing the frequency
        // of all elements
        Dictionary<int, int> mp = new Dictionary<int, int>();
        foreach (int value in arr)
        {
            if (mp.ContainsKey(value))
            {
                mp[value]++;
            }
            else
            {
                mp[value] = 1;
            }
        }
 
        // Dictionary for storing values associated
        // with a specific frequency
        Dictionary<int, List<int>> data = new Dictionary<int, List<int>>();
        foreach (var kvp in mp)
        {
            if (data.ContainsKey(kvp.Value))
            {
                data[kvp.Value].Add(kvp.Key);
            }
            else
            {
                data[kvp.Value] = new List<int> { kvp.Key };
            }
        }
 
        // Variable for calculating total cost
        int totalCost = 0;
 
        // Iterating over the data dictionary for
        // calculating minimum cost
        foreach (var kvp in data)
        {
            // Storing the list of elements
            // which have the same frequency in a
            // list
            List<int> values = kvp.Value;
 
            // If the number of elements which have the same
            // frequency is more than 1 then for
            // making them equal, we will pass them to
            // MinimumCost function
            if (values.Count > 1)
            {
                totalCost += kvp.Key * MinimumCost(values);
            }
        }
 
        // Returning the total calculated cost
        return totalCost;
    }
 
    // Drivers code
    static void Main()
    {
        List<int> arr = new List<int> { 1, 2, 3, 5, 3 };
 
        // Function call
        Console.WriteLine(MinCost(arr));
    }
}


Javascript




// Function to find the minimum cost to make all elements equal
function minimumCost(values) {
    // Function for finding the sum of all elements
    let sum = 0;
    for (let i = 0; i < values.length; i++) {
        sum += values[i];
    }
 
    // Calculate the average value
    let avg = Math.floor(sum / values.length);
 
    // Initialize the cost to 0
    let cost = 0;
    for (let i = 0; i < values.length; i++) {
        // Calculate the absolute difference of each element with the average
        cost += Math.abs(values[i] - avg);
    }
 
    // Return the minimum cost
    return cost;
}
 
// Function to find the total minimum cost
function minCost(arr) {
    // Map for storing the frequency of all elements
    let mp = new Map();
    for (let i = 0; i < arr.length; i++) {
        if (mp.has(arr[i])) {
            mp.set(arr[i], mp.get(arr[i]) + 1);
        } else {
            mp.set(arr[i], 1);
        }
    }
 
    // Map for storing values associated with a specific frequency
    let data = new Map();
    mp.forEach((value, key) => {
        if (data.has(value)) {
            data.get(value).push(key);
        } else {
            data.set(value, [key]);
        }
    });
 
    // Variable for calculating total cost
    let totalCost = 0;
 
    // Iterate over the data map for calculating minimum cost
    data.forEach((values, frequency) => {
        // If the number of elements with the same frequency is more than 1,
        // pass them to the minimumCost function to make them equal
        if (values.length > 1) {
            totalCost += frequency * minimumCost(values);
        }
    });
 
    // Return the total calculated cost
    return totalCost;
}
 
// Main function
function main() {
    const arr = [1, 2, 3, 5, 3];
 
    // Print the minimum cost
    console.log(minCost(arr));
}
 
main();


Output

4






Time Complexity: O(n*logn)
Auxiliary Space: O(n)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads