Given an array arr[] of length N, the task is to find the minimum number of operations to change the array such that each arr[i] occurs arr[i] times where in each operation either one element can be deleted from the array or one element can be inserted in the array.
Examples:
Input: N = 4, arr[ ] = {1, 1, 3, 3}
Output: 2
Explanation: Delete one occurrence of 1 from the array in one operation.
In another operation, insert element 3 in the array.
The final array will be [ 1, 3, 3, 3 ] where 1 occurs 1 time and 3 occurs 3 times.
Minimum 2 operations are needed. It cannot be reconstructed in less than 2 moves.
Input: N = 6, arr[ ] = {3, 3, 5,, 3, 2, 4}
Output: 3
Approach: The solution to the problem is based on the following idea:
For each array element (arr[i]), there are two choices: either delete all the occurrences of arr[i] or insert arr[i] such that number of occurrences is not same as its value.
Choose the minimum among the required number of deletions and insertions to minimize the total number of operations.
Follow the steps mentioned below to implement the idea:
- Store the frequency of all the elements
- Check if the frequency of the element is higher or greater than its value:
- If the frequency is higher than the best choice is to remove the element until the frequency becomes same as the current element.
- Else there are two choices:
- Delete all the occurrences of the element.
- Insert the element such that the frequency is same as its value.
- Add the minimum of these two in the final count of operations.
- Return the final count as the answer.
Below is the implementation for the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minOperations( int N, vector< int >& a)
{
unordered_map< int , int > mp;
for ( auto x : a) {
mp[x]++;
}
int operations = 0;
for ( auto x : mp) {
int occurrences = x.second;
if (occurrences > x.first) {
operations += (occurrences - x.first);
}
else if (occurrences < x.first) {
operations += min(occurrences,
x.first - occurrences);
}
}
return operations;
}
int main()
{
int N = 6;
vector< int > arr = { 3, 3, 5, 3, 2, 4 };
cout << minOperations(N, arr) << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.HashMap;
import java.util.Map;
class GFG {
static int minOperations( int N, int a[])
{
HashMap<Integer, Integer> mp = new HashMap<Integer, Integer>();
for ( int i = 0 ; i < N; i++){
if (mp.containsKey(a[i])){
mp.put(a[i], mp.get(a[i]) + 1 );
}
else {
mp.put(a[i], 1 );
}
}
int operations = 0 ;
int occurrences = 0 ;
for (Map.Entry<Integer, Integer> x : mp.entrySet()){
occurrences = x.getValue();
if (occurrences > x.getKey()) {
operations += (occurrences - x.getKey());
}
else if (occurrences < x.getKey()) {
operations += Math.min(occurrences,
x.getKey() - occurrences);
}
}
return operations;
}
public static void main (String[] args) {
int N = 6 ;
int arr[] = { 3 , 3 , 5 , 3 , 2 , 4 };
System.out.print(minOperations(N, arr));
}
}
|
Python3
from collections import Counter
def minOperations(N, a):
mp = dict (Counter(a))
operations = 0
for x in mp:
occurrences = mp[x]
if occurrences > x:
operations + = occurrences - x
elif occurrences < x:
operations + = min (occurrences, x - occurrences)
return operations
N = 6
arr = [ 3 , 3 , 5 , 3 , 2 , 4 ]
print (minOperations(N, arr))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int minOperations( int N, int [] a)
{
Dictionary< int , int > mp
= new Dictionary< int , int >();
for ( int i = 0; i < a.Length; i++) {
if (mp.ContainsKey(a[i])) {
mp[a[i]] = mp[a[i]] + 1;
}
else {
mp.Add(a[i], 1);
}
}
int operations = 0;
foreach (KeyValuePair< int , int > x in mp)
{
int occurrences = x.Value;
if (occurrences > x.Key) {
operations += (occurrences - x.Key);
}
else if (occurrences < x.Key) {
operations += Math.Min(occurrences,
x.Key - occurrences);
}
}
return operations;
}
public static void Main()
{
int N = 6;
int [] arr = { 3, 3, 5, 3, 2, 4 };
Console.Write(minOperations(N, arr));
}
}
|
Javascript
<script>
const minOperations = (N, a) => {
let mp = {};
for (let x in a) {
mp[a[x]] = a[x] in mp ? mp[a[x]] + 1 : 1;
}
let operations = 0;
for (let x in mp) {
let occurrences = mp[x];
if (occurrences > x) {
operations += (occurrences - x);
}
else if (occurrences < x) {
operations += Math.min(occurrences,
x - occurrences);
}
}
return operations;
}
let N = 6;
let arr = [3, 3, 5, 3, 2, 4];
document.write(minOperations(N, arr));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)