最小化 Array 元素的删除或插入,以使 arr[i] 将频率作为其值
给定一个长度为N的数组arr[] ,任务是找到改变数组的最小操作数,使得每个arr[i]发生arr[i]次,在每个操作中,可以从数组中删除一个元素或者可以在数组中插入一个元素。
例子:
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
方法:该问题的解决方案基于以下思路:
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.
按照下面提到的步骤来实现这个想法:
- 存储所有元素的频率
- 检查元素的频率是否高于或大于其值:
- 如果频率更高,那么最好的选择是移除元素,直到频率与当前元素相同。
- 否则有两种选择:
- 删除所有出现的元素。
- 插入元素,使频率与其值相同。
- 在最终的操作计数中添加这两个中的最小值。
- 返回最终计数作为答案。
以下是上述方法的实现:
C++
// C++ code to implement the approach
#include
using namespace std;
// Function to find out minimum
// number of operation
int minOperations(int N, vector& a)
{
// Map for storing frequency
// of the array elements
unordered_map mp;
for (auto x : a) {
mp[x]++;
}
// Variable to store the answer
int operations = 0;
for (auto x : mp) {
int occurrences = x.second;
// If the occurrence is greater
// than number then the greedy
// move is to remove extra occurrences
if (occurrences > x.first) {
operations += (occurrences - x.first);
}
// Else you can remove all the
// occurrences of the number or
// add the number sometimes until
// the occurrences of the number are
// not equal to the number itself so
// you have to take the minimum of
// all the occurrences
else if (occurrences < x.first) {
operations += min(occurrences,
x.first - occurrences);
}
}
// Return the operations
return operations;
}
// Driver code
int main()
{
int N = 6;
vector arr = { 3, 3, 5, 3, 2, 4 };
// Function call
cout << minOperations(N, arr) << endl;
return 0;
}
Java
// Java code to implement the approach
import java.io.*;
import java.util.HashMap;
import java.util.Map;
class GFG {
// Function to find out minimum
// number of operation
static int minOperations(int N, int a[])
{
// Map for storing frequency
// of the array elements
HashMap mp = new HashMap();
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);
}
}
// Variable to store the answer
int operations = 0;
int occurrences = 0;
for (Map.Entry x : mp.entrySet()){
occurrences = x.getValue();
// If the occurrence is greater
// than number then the greedy
// move is to remove extra occurrences
if (occurrences > x.getKey()) {
operations += (occurrences - x.getKey());
}
// Else you can remove all the
// occurrences of the number or
// add the number sometimes until
// the occurrences of the number are
// not equal to the number itself so
// you have to take the minimum of
// all the occurrences
else if (occurrences < x.getKey()) {
operations += Math.min(occurrences,
x.getKey() - occurrences);
}
}
// Return the operations
return operations;
}
// Driver code
public static void main (String[] args) {
int N = 6;
int arr[] = { 3, 3, 5, 3, 2, 4 };
// Function call
System.out.print(minOperations(N, arr));
}
}
Python3
# Python3 code to implement the above approach
from collections import Counter
# function to calculate the no of operations
def minOperations(N, a):
# a dictionary that stores the frequencies
mp = dict(Counter(a))
# variable to store the operations
operations = 0
# if occurrence > x, then the greedy move is
# to remove extra occurrences
for x in mp:
occurrences = mp[x]
if occurrences > x:
operations += occurrences - x
# else, you can remove all the occurrences of the no
# or add x until the occurrences
# of x are not equal to x itself.
elif occurrences < x:
operations += min(occurrences, x - occurrences)
# return the operations
return operations
# Driver Code
N = 6
arr = [3, 3, 5, 3, 2, 4]
print(minOperations(N, arr))
# This code is contributed by phasing17
C#
// C# code to implement the approach
using System;
using System.Collections.Generic;
class GFG {
// Function to find out minimum
// number of operation
static int minOperations(int N, int[] a)
{
// Map for storing frequency
// of the array elements
Dictionary mp
= new Dictionary();
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);
}
}
// Variable to store the answer
int operations = 0;
foreach(KeyValuePair x in mp)
{
int occurrences = x.Value;
// If the occurrence is greater
// than number then the greedy
// move is to remove extra occurrences
if (occurrences > x.Key) {
operations += (occurrences - x.Key);
}
// Else you can remove all the
// occurrences of the number or
// add the number sometimes until
// the occurrences of the number are
// not equal to the number itself so
// you have to take the minimum of
// all the occurrences
else if (occurrences < x.Key) {
operations += Math.Min(occurrences,
x.Key - occurrences);
}
}
// Return the operations
return operations;
}
// Driver code
public static void Main()
{
int N = 6;
int[] arr = { 3, 3, 5, 3, 2, 4 };
// Function call
Console.Write(minOperations(N, arr));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
3
时间复杂度: O(N)
辅助空间: O(N)