Open In App

Minimize deletion or append to make consecutive occurrence of all elements equal

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of size N having positive elements, the task is to find the minimum number of deletion or append operations to make consecutive occurrences of all elements equal.

Examples: 

Input: N = 4, arr[] = {1, 1, 2, 2}
Output: 0
Explanation: All the consecutive elements have the same value and same frequency already. Therefore, no operation is required. 

Input: N = 8, arr[] = {5, 5, 5, 6, 2, 2, 5, 5},  
Output: 2
Explanation: 
First Operation: Choose i = 3 and put 6 at right side of i. Then updated arr[] is: {5, 5, 5, 6, 6, 2, 2, 5, 5}.
Second Operation: Choose i = 2 and remove it from arr[]. Then updated arr[] is: {5, 5, 6, 6, 2, 2, 5, 5}.

Approach: Implement the idea below to solve the problem

The problem can be solved is based on the mathematical concept of the median value.

In N numbers, the median is the number that has the least sum difference from all of the numbers present. Same in the problem we have to find the minimum number of operations such that all the elements have the same frequency. Therefore, we need to find a frequency of an element which has the least sum difference from all of the present frequencies. So, we can use the concept of the median here.

Follow the below illustration for a better understanding.

Illustration:

Consider N = 8, arr[] = {5, 5, 5, 6, 2, 2, 5, 5}

Frequencies of same consecutive elements: {5: 3, 6: 1, 2: 2, 5: 2}, get all the frequencies in Frequency array.

Frequency[] = {3, 1, 2, 2}
Sorted frequency[] = {1, 2, 2, 3}
median = Frequency[frequency.Length/2] = frequency[4/2] = frequency[2] = 2

Absolute difference of all numbers with median:
|1 – 2|=1
|2 – 2|=0
|2 – 2|=0
|3 – 2|=1
Sum of absolute differences = Minimum number of operations required = 1+0+0+1 = 2
Total operations = 2

Follow the below steps to implement the idea:

  1. Create an ArrayList to hold frequencies, let us say frequency[]
  2. Traverse on input arr[], get frequencies of consecutive elements having the same value and store them in frequency.
    • If frequency.size() = 1, Return minimum cost as 0.
    • Else calculate the sum of differences from the median and return the sum of differences.

Below is the implementation of the above approach:

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function for returning minimum cost
int MinCost(int arr[], int n)
{
    // List for storing frequencies of consecutive elements having same values
    vector<int> frequencies;
 
    // Starting point of arr[]
    int leftEnd = 1;
    int count = 1;
    int prev = arr[0];
    // While Loop for calculate frequencies
    while (leftEnd < n) {
 
        // Prev element and current element are equal
        if (prev == arr[leftEnd]) {
 
            count++;
        }
        else {
            frequencies.push_back(count);
            count = 1;
            prev = arr[leftEnd];
        }
 
        leftEnd++;
    }
    frequencies.push_back(count);
 
    // Sorting frequencies for getting
    // median frequency
    sort(frequencies.begin(), frequencies.end());
 
    // If list has size = 1
    // Means that there is only same
    // valued elements present in arr[]
    if (frequencies.size() == 1) {
 
        // Returning min cost 0 for no operations
        return 0;
    }
    else {
 
        // getting Median from list
        int median = frequencies[frequencies.size() / 2];
 
        // variable to store number of operations
        // required
        int operations = 0;
 
        // Loop for traversing on sorted list
        for (int i = 0; i < frequencies.size(); i++) {
 
            // Adding sum of differences with median
            operations += abs(frequencies[i] - median);
        }
 
        // Returning min operations
        return operations;
    }
}
 
int main()
{
    int N = 8;
    int arr[] = { 5, 5, 5, 6, 2, 2, 5, 5 };
 
    // Function call
    cout << (MinCost(arr, N));
}


Java




// Java code to implement the approach
 
import java.lang.*;
import java.util.ArrayList;
 
class GFG {
    public static void main(String[] args)
    {
        int N = 8;
        int[] arr = { 5, 5, 5, 6, 2, 2, 5, 5 };
 
        // Function call
        System.out.println(MinCost(arr, N));
    }
 
    // Function for returning minimum cost
    static int MinCost(int[] arr, int n)
    {
        // List for storing frequencies of
        // consecutive elements having same values
        ArrayList<Integer> frequencies = new ArrayList<>();
 
        // Starting point of arr[]
        int leftEnd = 1;
        int count = 1;
        int prev = arr[0];
        // While Loop for calculate frequencies
        while (leftEnd < n) {
 
            // Prev element and current element
            // are equal
            if (prev == arr[leftEnd]) {
 
                count++;
            }
            else {
                frequencies.add(count);
                count = 1;
                prev = arr[leftEnd];
            }
 
            leftEnd++;
        }
        frequencies.add(count);
 
        // Sorting frequencies for getting
        // median frequency
        frequencies.sort(null);
 
        // If list has size = 1
        // Means that there is only same
        // valued elements present in arr[]
        if (frequencies.size() == 1) {
 
            // Returning min cost 0 for no operations
            return 0;
        }
        else {
 
            // getting Median from list
            int median
                = frequencies.get(frequencies.size() / 2);
 
            // variable to store number of operations
            // required
            int operations = 0;
 
            // Loop for traversing on sorted list
            for (int i = 0; i < frequencies.size(); i++) {
 
                // Adding sum of differences with median
                operations += Math.abs(frequencies.get(i)
                                       - median);
            }
 
            // Returning min operations
            return operations;
        }
    }
}


Python3




# Python code to implement the approach
 
# Function for returning minimum cost
def MinCost(arr, n):
    # List for storing frequencies of
    # consecutive elements having same values
    frequencies = []
 
    # Starting point of arr[]
    leftEnd = 1
    count = 1
    prev = arr[0]
    # While Loop for calculate frequencies
    while leftEnd < n:
        # Prev element and current element
        # are equal
        if prev == arr[leftEnd]:
            count += 1
        else:
            frequencies.append(count)
            count = 1
            prev = arr[leftEnd]
        leftEnd += 1
    frequencies.append(count)
 
    # Sorting frequencies for getting
    # median frequency
    frequencies.sort()
 
    # If list has size = 1
    # Means that there is only same
    # valued elements present in arr[]
    if len(frequencies) == 1:
        # Returning min cost 0 for no operations
        return 0
    else:
        # getting Median from list
        median = frequencies[len(frequencies) // 2]
 
        # variable to store number of operations
        # required
        operations = 0
 
        # Loop for traversing on sorted list
        for i in range(len(frequencies)):
            # Adding sum of differences with median
            operations += abs(frequencies[i] - median)
 
        # Returning min operations
        return operations
 
 
N = 8
arr = [5, 5, 5, 6, 2, 2, 5, 5]
 
# Function call
print(MinCost(arr, N))
 
# This code is contributed by lokesh.


C#




// C# code to implement the approach
using System;
using System.Collections.Generic;
 
public class GFG {
    static public void Main()
    {
        int N = 8;
        int[] arr = { 5, 5, 5, 6, 2, 2, 5, 5 };
 
        // Function call
        Console.WriteLine(MinCost(arr, N));
    }
 
    // Function for returning minimum cost
    static int MinCost(int[] arr, int n)
    {
        // List for storing frequencies of
        // consecutive elements having same values
        List<int> frequencies = new List<int>();
 
        // Starting point of arr[]
        int leftEnd = 1;
        int count = 1;
        int prev = arr[0];
        // While Loop for calculate frequencies
        while (leftEnd < n) {
            // Prev element and current element
            // are equal
            if (prev == arr[leftEnd]) {
                count++;
            }
            else {
                frequencies.Add(count);
                count = 1;
                prev = arr[leftEnd];
            }
 
            leftEnd++;
        }
        frequencies.Add(count);
 
        // Sorting frequencies for getting
        // median frequency
        frequencies.Sort();
 
        // If list has size = 1
        // Means that there is only same
        // valued elements present in arr[]
        if (frequencies.Count == 1) {
            // Returning min cost 0 for no operations
            return 0;
        }
        else {
            // getting Median from list
            int median = frequencies[frequencies.Count / 2];
 
            // variable to store number of operations
            // required
            int operations = 0;
 
            // Loop for traversing on sorted list
            for (int i = 0; i < frequencies.Count; i++) {
                // Adding sum of differences with median
                operations
                    += Math.Abs(frequencies[i] - median);
            }
 
            // Returning min operations
            return operations;
        }
    }
}
 
// This code is contributed by lokeshmvs21.


Javascript




// JavaScript code to implement the approach
 
// Function for returning minimum cost
function MinCost(arr, n)
    {
        // List for storing frequencies of consecutive elements having same values
        let frequencies=[];
 
        // Starting point of arr[]
        let leftEnd = 1;
        let count = 1;
        let prev = arr[0];
        // While Loop for calculate frequencies
        while (leftEnd < n) {
 
            // Prev element and current element are equal
            if (prev == arr[leftEnd]) {
 
                count++;
            }
            else {
                frequencies.push(count);
                count = 1;
                prev = arr[leftEnd];
            }
 
            leftEnd++;
        }
        frequencies.push(count);
 
        // Sorting frequencies for getting
        // median frequency
        frequencies.sort();
 
        // If list has size = 1
        // Means that there is only same
        // valued elements present in arr[]
        if (frequencies.length == 1) {
 
            // Returning min cost 0 for no operations
            return 0;
        }
        else {
 
            // getting Median from list
            let median = frequencies[frequencies.length / 2];
 
            // variable to store number of operations
            // required
            let operations = 0;
 
            // Loop for traversing on sorted list
            for (let i = 0; i < frequencies.length; i++) {
 
                // Adding sum of differences with median
                operations += Math.abs(frequencies[i] - median);
            }
 
            // Returning min operations
            return operations;
        }
    }
 
        let N = 8;
        let arr = [5, 5, 5, 6, 2, 2, 5, 5 ];
 
        // Function call
        console.log((MinCost(arr, N)));
         
        // This code is contributed by poojaagarwal2.


Output

2

Time Complexity: O(N*logN)
Auxiliary Space: O(N)

Another Approach:

  1. Sort the input array arr[].
  2. Initialize two pointers i and j to the beginning of the array.
  3. Traverse the array with the pointers i and j such that i <= j < n, where n is the length of the array.
  4. If arr[i] is equal to arr[j], increment j. Otherwise, calculate the frequency of arr[i] as j – i and store it in a variable freq. Increment i to j and set j to i+1.
  5. Store the frequency freq in a vector frequencies.
  6. After the loop, if the value of i is less than n, then the last element in the array has a frequency of n – i. Store this frequency in frequencies as well.
  7. Sort the vector frequencies.
  8. Calculate the median as frequencies[frequencies.size()/2].
  9. Calculate the sum of absolute differences of all frequencies in the vector frequencies from the median. This sum is the minimum number of 
  10. operations required to make consecutive occurrences of all elements equal.

Below is the implementation of the above approach:

C++




// C++ code to implement the improved approach
#include <bits/stdc++.h>
using namespace std;
// Function for returning minimum cost
int MinCost(int arr[], int n)
{
    // Sort the input array
    sort(arr, arr + n);
    // Initialize pointers
    int i = 0, j = 0;
 
    // Vector for storing frequencies
    vector<int> frequencies;
 
    // Loop to calculate frequencies
    while (i < n && j < n) {
        if (arr[i] == arr[j]) {
            j++;
        }
        else {
            int freq = j - i;
            frequencies.push_back(freq);
            i = j;
            j++;
        }
    }
 
    // Handle the last element separately
    int freq = n - i;
    frequencies.push_back(freq);
 
    // Sort the vector frequencies
    sort(frequencies.begin(), frequencies.end());
 
    // If list has size = 1
    // Means that there is only same
    // valued elements present in arr[]
    if (frequencies.size() == 1) {
        // Returning min cost 0 for no operations
        return 0;
    }
    else {
        // Getting median from list
        int median = frequencies[frequencies.size() / 2];
 
        // Variable to store number of operations required
        int operations = 0;
 
        // Loop for traversing on sorted list
        for (int i = 0; i < frequencies.size(); i++) {
            // Adding sum of differences with median
            operations += abs(frequencies[i] - median);
        }
 
        // Returning min operations
        return operations;
    }
}
 
int main()
{
    int N = 8;
    int arr[] = { 5, 5, 5, 6, 2, 2, 5, 5 };
    // Function call
    cout << (MinCost(arr, N));
}


Java




// Java code to implement the improved approach
import java.util.*;
 
public class GFG {
 
    // Function for returning minimum cost
    public static int MinCost(int[] arr, int n)
    {
 
        // Sort the input array
        Arrays.sort(arr);
 
        // Initialize pointers
        int i = 0, j = 0;
 
        // ArrayList for storing frequencies
        ArrayList<Integer> frequencies = new ArrayList<>();
 
        // Loop to calculate frequencies
        while (i < n && j < n) {
            if (arr[i] == arr[j]) {
                j++;
            }
            else {
                int freq = j - i;
                frequencies.add(freq);
                i = j;
                j++;
            }
        }
 
        // Handle the last element separately
        int freq = n - i;
        frequencies.add(freq);
 
        // Sort the ArrayList frequencies
        Collections.sort(frequencies);
 
        // If list has size = 1
        // Means that there is only same valued elements present in arr[]
        if (frequencies.size() == 1) {
            // Returning min cost 0 for no operations
            return 0;
        }
        else {
            // Getting median from list
            int median = frequencies.get(frequencies.size() / 2);
 
            // Variable to store number of operations required
            int operations = 0;
 
            // Loop for traversing on sorted list
            for (int k = 0; k < frequencies.size(); k++) {
                // Adding sum of differences with median
                operations += Math.abs(frequencies.get(k) - median);
            }
 
            // Returning min operations
            return operations;
        }
    }
 
    public static void main(String[] args)
    {
        int N = 8;
        int[] arr = { 5, 5, 5, 6, 2, 2, 5, 5 };
 
        // Function call
        System.out.println(MinCost(arr, N));
    }
}


Python3




# Python code to implement the improved approach
from typing import List
 
# Function for returning minimum cost
def MinCost(arr: List[int], n: int) -> int:
    # Sort the input array
    arr.sort()
    # Initialize pointers
    i, j = 0, 0
 
    # List for storing frequencies
    frequencies = []
 
    # Loop to calculate frequencies
    while i < n and j < n:
        if arr[i] == arr[j]:
            j += 1
        else:
            freq = j - i
            frequencies.append(freq)
            i = j
            j += 1
 
    # Handle the last element separately
    freq = n - i
    frequencies.append(freq)
 
    # Sort the list of frequencies
    frequencies.sort()
 
    # If list has size = 1
    # Means that there is only same
    # valued elements present in arr[]
    if len(frequencies) == 1:
        # Returning min cost 0 for no operations
        return 0
    else:
        # Getting median from list
        median = frequencies[len(frequencies)//2]
 
        # Variable to store number of operations required
        operations = 0
 
        # Loop for traversing on sorted list
        for freq in frequencies:
            # Adding sum of differences with median
            operations += abs(freq - median)
 
        # Returning min operations
        return operations
 
# Driver code
arr = [5, 5, 5, 6, 2, 2, 5, 5]
N = len(arr)
# Function call
print(MinCost(arr, N))


C#




// C# code to implement the improved approach
 
using System;
using System.Linq;
 
class GFG {
 
    // Function for returning minimum cost
    static int MinCost(int[] arr, int n)
    {
        // Sort the input array
        Array.Sort(arr);
 
        // Initialize pointers
        int i = 0, j = 0;
 
        // Array for storing frequencies
        int[] frequencies = new int[n];
 
        // Loop to calculate frequencies
        while (i < n && j < n) {
            if (arr[i] == arr[j]) {
                j++;
            }
            else {
                int freqn = j - i;
                frequencies[i] = freqn;
                i = j;
                j++;
            }
        }
 
        // Handle the last element separately
        int freq = n - i;
        frequencies[i] = freq;
 
        // Remove the extra zeros in the array
        frequencies
            = frequencies.Where(x = > x != 0).ToArray();
 
        // Sort the array frequencies
        Array.Sort(frequencies);
 
        // If list has size = 1
        // Means that there is only same
        // valued elements present in arr[]
        if (frequencies.Length == 1) {
 
            // Returning min cost 0 for no operations
            return 0;
        }
        else {
 
            // Getting median from list
            int median
                = frequencies[frequencies.Length / 2];
 
            // Variable to store number of operations
            // required
            int operations = 0;
 
            // Loop for traversing on sorted list
            for (int k = 0; k < frequencies.Length; k++) {
                // Adding sum of differences with median
                operations
                    += Math.Abs(frequencies[k] - median);
            }
 
            // Returning min operations
            return operations;
        }
    }
 
    static void Main()
    {
        int N = 8;
        int[] arr = { 5, 5, 5, 6, 2, 2, 5, 5 };
 
        // Function call
        Console.WriteLine(MinCost(arr, N));
    }
}


Javascript




// JavaScript code to implement the improved approach
 
function MinCost(arr){
    // Sort the input array
    arr.sort((a, b) => a - b);
    // Initialize pointers
    let i = 0, j = 0;
 
    // Array for storing frequencies
    let frequencies = [];
 
    // Loop to calculate frequencies
    while (i < arr.length && j < arr.length) {
        if (arr[i] === arr[j]) {
            j++;
        }
        else {
            let freq = j - i;
            frequencies.push(freq);
            i = j;
            j++;
        }
    }
 
    // Handle the last element separately
    let freq = arr.length - i;
    frequencies.push(freq);
 
    // Sort the array frequencies
    frequencies.sort((a, b) => a - b);
 
    // If list has size = 1
    // Means that there is only same
    // valued elements present in arr[]
    if (frequencies.length === 1) {
        // Returning min cost 0 for no operations
        return 0;
    }
    else {
        // Getting median from list
        let x = Math.floor(frequencies.length / 2);
        let median = frequencies[x];
 
        // Variable to store number of operations required
        let operations = 0;
 
        // Loop for traversing on sorted list
        for (let i = 0; i < frequencies.length; i++) {
            // Adding sum of differences with median
            operations += Math.abs(frequencies[i] - median);
        }
 
        // Returning min operations
        return operations;
    }
}
 
let arr = [ 5, 5, 5, 6, 2, 2, 5, 5 ];
// Function call
console.log(MinCost(arr));


Output

4

Time Complexity: O(N*logN)

Auxiliary Space : O(N)

Related articles:



Last Updated : 10 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads