Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Minimum operations for which all integers from [0, N] appears as smallest positive missing number (MEX)

  • Last Updated : 21 Feb, 2022

Given an array arr[], of size N the task is to find the minimum operations on the array such that in each operation any element in the array can be chosen and incremented by 1 so that the MEX is i for all i in the range [0, n]. If for any i if the MEX is not i print -1.

Examples : 

Input : arr[] = {3, 0, 1, 0, 3}
Output: 
MEX for i = 0 is 2
MEX for i = 1 is 1
MEX for i = 2 is 0
MEX for i = 3 is 4
MEX for i = 4 is 2
MEX for i = 5 is 3
Explanation: 
For MEX = 0 
In operation 1 choose index 1 and increment it by 1 
In operation 2 choose index 3 and increment it by 1 the array becomes {3, 1, 1, 1, 3} MEX = 0. So 2 operations.
For MEX =1
In operation 1 choose index 2 and increment  it by 1 the array becomes {3, 0, 2, 0, 3} MEX = 1. So 1 operation.
For MEX = 2, So 0 operation.
It is already having MEX = 2 
For MEX = 3
In operation 1 choose index 0 and increment it by 1 
In operation 2 choose index 3 and increment it by 1
In operation 3 choose index 1 and increment it by 1  
In operation 3 choose index 1 and increment it by 1  , the array becomes {4, 2, 1, 0, 4} MEX = 3 so 4 operations.
Same for MEX = 4, 5 .

Input : {1, 2, 3, 4}
Output: 0 -1, -1, -1, -1
MEX for i = 0 is 0
MEX for i = 1 is -1
MEX for i = 2 is -1
MEX for i = 3 is -1
MEX for i = 4 is -1

 

Approach: Hashing can be used to solve this problem to store the frequencies of the element and the stack can be used to store the repeated elements in the array. Hashmap can be used to store the frequencies for a MEX = i if i already exists in the hashmap increment all that occurrences and store the repeated elements in the stack else if the frequency of i is 0 it is already a MEX so 0 operations, Now look for the repeating occurrences in the stack and make it to current i so that for i+1, i would not become MEX. Follow these steps to solve this problem:

  • Initialize an unordered_map freq[] to store the frequencies of the array arr[] and a variable is_possible to keep track of the possibility of MEX.
  • Iterate through the array arr[] and store the frequencies in the hashmap freq.
  • Initialize the stack stk[] and the vector ops,  to store the minimum operations for MEX = i, prev_cost to store the cost required to increment the repeated element.
  • If is_possible == 0, MEX = i is not possible so store -1.
  • Else store freq[i]+ prev_cost in the ops.
    • If freq[i] is equal to 0 Check if there is some element in the stack pop it and increment it to i and increment prev_cost to i-j and increment freq[i], if the stack is empty make is_possible to false.
    • Else if the freq[i]>1 push the repeated into the stack stk[] and decrement freq[i].
  • Now print the vector ops which contains the minimum operations to make the MEX = i [0, n].

Below is the implementation of the above approach.

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the minimum operations
// to make the MEX = i
void find_min_operations(int arr[], int n)
{
 
    // Initialize an unordered_map
    // to store the frequencies
    unordered_map<int, int> freq;
 
    // is_possible to store
    // the possibility of MEX = i
    bool is_possible = true;
 
    // count the frequencies
    // and store into the freq
    for (int i = 0; i < n; i++) {
        freq[arr[i]]++;
    }
 
    // Initialize stack to store
    // the repeated elements
    stack<int> stk;
 
    // ops store the minimum
    // operations required for MEX =i
    vector<int> ops;
 
    // prev_cost to store the
    // cost to increment some
    // repeated element to i-1
    // if MEX initially is i-1 so
    // that  MEX remains i
    int prev_cost = 0;
    for (int i = 0; i <= n; i++) {
 
        // Push -1 if it is not possible
        if (is_possible == 0)
            ops.push_back(-1);
        else {
 
            ops.push_back(freq[i] + prev_cost);
 
            // If frequency of the element is 0
            // then check for repeated element
            // in the stack so that it can be added
            // with i-j operations in next iteration
            // and can be made it to i.
            if (freq[i] == 0) {
 
                // Check for repeated
                // element in the stack
                if (!stk.empty()) {
                    int j = stk.top();
                    stk.pop();
                    prev_cost += i - j;
                    // Increment the frequency of i since
                    // the repeated element j is made to i
 
                    freq[i]++;
                }
 
                // If no repeated element
                // no possibility for MEX = i+1
                // so make is_possible=false
                else
                    is_possible = false;
            }
 
            // If i is already available
            else {
 
                // Push the repeated elements
                // into the stack
                while (freq[i] > 1) {
                    stk.push(i);
                    freq[i]--;
                }
            }
        }
    }
 
    for (int i = 0; i < ops.size(); i++) {
        cout << "MEX for i = "
             << i << " is " << ops[i]
             << endl;
    }
}
 
// Driver Code
int main()
{
 
    // Initializing array arr[]
    int arr[] = { 3, 0, 1, 0, 3 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function call
    find_min_operations(arr, n);
    return 0;
}

Python3




# Python3 program for the above approach
from collections import deque
 
# Function to find the minimum operations
# to make the MEX = i
def find_min_operations(arr, n):
     
    # Initialize an unordered_map
    # to store the frequencies
    freq = {}
 
    # is_possible to store
    # the possibility of MEX = i
    is_possible = True
 
    # Count the frequencies
    # and store into the freq
    for i in range(0, n):
        if arr[i] in freq:
            freq[arr[i]] += 1
        else:
            freq[arr[i]] = 1
 
    # Initialize stack to store
    # the repeated elements
    stk = deque()
 
    # ops store the minimum
    # operations required for MEX =i
    ops = []
 
    # prev_cost to store the
    # cost to increment some
    # repeated element to i-1
    # if MEX initially is i-1 so
    # that MEX remains i
    prev_cost = 0
    for i in range(0, n + 1):
 
        # Push -1 if it is not possible
        if (is_possible == 0):
            ops.append(-1)
        else:
            if i in freq:
                ops.append(freq[i] + prev_cost)
            else:
                ops.append(prev_cost)
 
            # If frequency of the element is 0
            # then check for repeated element
            # in the stack so that it can be added
            # with i-j operations in next iteration
            # and can be made it to i.
            if (not (i in freq)):
 
                # Check for repeated
                # element in the stack
                if (len(stk) != 0):
                    j = stk.popleft()
                    prev_cost += i - j
                     
                    # Increment the frequency of i since
                    # the repeated element j is made to i
                    freq[i] = freq[i] + 1 if i in freq else 1
 
                # If no repeated element
                # no possibility for MEX = i+1
                # so make is_possible=false
                else:
                    is_possible = False
 
            # If i is already available
            else:
 
                # Push the repeated elements
                # into the stack
                while (freq[i] > 1):
                    stk.append(i)
                    freq[i] -= 1
 
    for i in range(0, len(ops)):
        print(f"MEX for i = {i} is {ops[i]}")
 
# Driver Code
if __name__ == "__main__":
 
    # Initializing array arr[]
    arr = [ 3, 0, 1, 0, 3 ]
    n = len(arr)
 
    # Function call
    find_min_operations(arr, n)
 
# This code is contributed by rakeshsahni
Output
MEX for i = 0 is 2
MEX for i = 1 is 1
MEX for i = 2 is 0
MEX for i = 3 is 4
MEX for i = 4 is 2
MEX for i = 5 is 3

Time Complexity: O(N)  where N is the size of the array
Auxiliary Space: O(N)

 


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!