Open In App

Minimum Increments to reach the given MEX

Last Updated : 12 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of size N. In one operation, choose any element of the array and increase its value by 1. The task is to determine the minimum operations to make the MEX of the array equal to i, for each i from 0 to N. The MEX of the array is equal to the minimum non-negative integer that is not in the array.

Examples:

Input: N = 3, arr[] = {0, 1, 3}
Output: 1 1 0 -1
Explanation:

  • For i = 0, MEX = 0. So, we need to perform 1 operation to get the MEX as 0:
    • increment arr[0] by 1, arr[] = {1, 1, 3}
  • For i = 1, MEX = 1. So, we need to perform 1 operation to get the MEX as 0.
    • increment arr[1] by 1, arr[] = {0, 2, 3}
  • For i = 2, MEX = 2, So we don’t need to perform any operation, as MEX is already equal to 2.
  • For i = 3, MEX = 3, We cannot have MEX = 3 by performing any number of operations.

Input: N = 4, arr[] = {3, 0, 0, 0}
Output: 3 0 1 4 3
Explanation:

  • For i = 0, MEX = 0. So, we need to perform 3 operations to get MEX as 0.
    • increment arr[1] by 1, arr[] = {3, 1, 0, 0}
    • increment arr[2] by 1, arr[] = {3, 1, 1, 0}
    • increment arr[3] by 1, arr[] = {3, 1, 1, 1}
  • For i = 1, MEX = 1, so we don’t need to perform any operation, as MEX is already equal to 1.
  • For i = 2, MEX = 2, so we need to perform 1 operation to get MEX as 2.
    • increment arr[1] by 1, arr[] = {3, 1, 0, 0}
  • For i = 3, MEX = 3, so we need to perform 4 operations to get MEX as 3.
    • increment arr[1] by 1, arr[] = {3, 1, 0, 0}
    • increment arr[2] by 1, arr[] = {3, 1, 1, 0}
    • increment arr[2] by 1, arr[] = {3, 1, 2, 0}
    • increment arr[0] by 1, arr[] = {4, 1, 2, 0}
  • For i = 4, MEX = 4, so we need to perform 3 operations to get MEX as 4.
    • increment arr[1] by 1, arr[] = {3, 1, 0, 0}
    • increment arr[2] by 1, arr[] = {3, 1, 1, 0}
    • increment arr[2] by 1, arr[] = {3, 1, 2, 0}

Approach: To solve the problem, follow the below idea:

To solve the problem, we can first sort the array in ascending order and then start traversing the array from left to right. To make the MEX of array = 0, we have to increment all the existing 0s by 1. Now, to make the MEX of the array = X, we first make the MEX = X – 1, and then if X – 1, is not in the array then we need to convert the largest extra number (in range 1 to X – 2) and increment it to make it equal to (X – 1). If at any point there is no extra number in range (1, X – 2), then we cannot make MEX for any value >= X.

Now, in order to get the greatest extra value at any index, we can use a stack to store the extra values. Multiple occurrences should be pushed multiple times and since we are traversing the array in non-decreasing order, so at any index i, the top of the stack will always have the largest extra number <= arr[i].

Step-by-step algorithm:

  • Iterate through the values from 0 to N.
  • If p is 1, print “-1” and continue to the next iteration.
  • Otherwise, print x + a[i], where x is the current sum and a[i] is the frequency of the current value in the array.
  • Push i into the stack s a[i] times.
  • If the stack is empty (s.size() == 0), set p to 1.
  • Otherwise, update x by adding i – s.top() and pop the top element from the stack.

Below is the implementation of the approach:

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    long long i, j, x, n, t, p;

    // Input values
    n = 3;
    long long inputValues[] = {0, 1, 3};

    x = 0;
    p = 0;
    long long a[n + 1];

    // Initialize array 'a' with zeros
    for (i = 0; i <= n; i++) {
        a[i] = 0;
    }

    stack<long long> s;

    // Count occurrences of each value in the input array
    for (i = 1; i <= n; i++) {
        x = inputValues[i - 1];
        a[x]++;
    }

    x = 0;

    // Iterate through the array and perform the required operations
    for (i = 0; i <= n; i++) {
        if (p == 1) {
            // If 'p' is 1, print -1 and continue
            cout << "-1 ";
            continue;
        }

        // Print the current value of 'x' plus the count of occurrences of 'i'
        cout << x + a[i] << " ";

        // Push 'i' into the stack 'a[i]' times
        for (j = 0; j < a[i]; j++) {
            s.push(i);
        }

        // Check if the stack is empty
        if (s.size() == 0)
            p = 1; // Set 'p' to 1 if the stack is empty
        else {
            // Update 'x' by adding 'i' minus the top element of the stack
            x = x + i - s.top();
            s.pop(); // Pop the top element from the stack
        }
    }

    return 0;
}
Java
import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        long i, j, x, n, t, p;

        // Input values
        n = 3;
        long[] inputValues = {0, 1, 3};

        x = 0;
        p = 0;
        int[] a = new int[(int) (n + 1)];  // Change the type to int

        // Initialize array 'a' with zeros
        for (i = 0; i <= n; i++) {
            a[(int) i] = 0;
        }

        Stack<Long> s = new Stack<>();

        // Count occurrences of each value in the input array
        for (i = 1; i <= n; i++) {
            x = inputValues[(int) (i - 1)];
            a[(int) x]++;
        }

        x = 0;

        // Iterate through the array and perform the required operations
        for (i = 0; i <= n; i++) {
            if (p == 1) {
                // If 'p' is 1, print -1 and continue
                System.out.print("-1 ");
                continue;
            }

            // Print the current value of 'x' plus the count of occurrences of 'i'
            System.out.print(x + a[(int) i] + " ");

            // Push 'i' into the stack 'a[i]' times
            for (j = 0; j < a[(int) i]; j++) {
                s.push(i);
            }

            // Check if the stack is empty
            if (s.size() == 0)
                p = 1; // Set 'p' to 1 if the stack is empty
            else {
                // Update 'x' by adding 'i' minus the top element of the stack
                x = x + i - s.peek();
                s.pop(); // Pop the top element from the stack
            }
        }
    }
}
C#
// C# program for the above approach
using System;
using System.Collections.Generic;

public class GFG {
    public static void Main()
    {
        long i, j, x, n, p;

        // Input values
        n = 3;
        long[] inputValues = { 0, 1, 3 };

        x = 0;
        p = 0;
        long[] a = new long[n + 1];

        // Initialize array 'a' with zeros
        for (i = 0; i <= n; i++) {
            a[i] = 0;
        }

        Stack<long> s = new Stack<long>();

        // Count occurrences of each value in the input
        // array
        for (i = 1; i <= n; i++) {
            x = inputValues[i - 1];
            a[x]++;
        }

        x = 0;

        // Iterate through the array and perform the
        // required operations
        for (i = 0; i <= n; i++) {
            if (p == 1) {
                // If 'p' is 1, print -1 and continue
                Console.Write("-1 ");
                continue;
            }

            // Print the current value of 'x' plus the count
            // of occurrences of 'i'
            Console.Write(x + a[i] + " ");

            // Push 'i' into the stack 'a[i]' times
            for (j = 0; j < a[i]; j++) {
                s.Push(i);
            }

            // Check if the stack is empty
            if (s.Count == 0)
                p = 1; // Set 'p' to 1 if the stack is empty
            else {
                // Update 'x' by adding 'i' minus the top
                // element of the stack
                x = x + i - s.Peek();
                s.Pop(); // Pop the top element from the
                         // stack
            }
        }
    }
}

// This code is contributed by Susobhan Akhuli
Javascript
let n = 3;
let input_values = [0, 1, 3];

let x = 0;
let p = 0;
let a = new Array(n + 1).fill(0);

// Count occurrences of each value in the input array
for (let value of input_values) {
  a[value] += 1;
}

x = 0;
let stack = [];

// Iterate through the array and perform the required operations
let output = "";
for (let i = 0; i < n + 1; i++) {
  if (p === 1) {
    // If 'p' is 1, print -1 and continue
    output += "-1 ";
    continue;
  }

  // Print the current value of 'x' plus the count of occurrences of 'i'
  output += (x + a[i]) + " ";

  // Push 'i' into the stack 'a[i]' times
  for (let j = 0; j < a[i]; j++) {
    stack.push(i);
  }

  // Check if the stack is empty
  if (stack.length === 0) {
    p = 1; // Set 'p' to 1 if the stack is empty
  } else {
    // Update 'x' by adding 'i' minus the top element of the stack
    x = x + i - stack.pop(); // Pop the top element from the stack
  }
}

console.log(output.trim()); // Output the result in a single line
Python3
n = 3
input_values = [0, 1, 3]

x = 0
p = 0
a = [0] * (n + 1)

# Count occurrences of each value in the input array
for value in input_values:
    a[value] += 1

x = 0
stack = []

# Iterate through the array and perform the required operations
for i in range(n + 1):
    if p == 1:
        # If 'p' is 1, print -1 and continue
        print("-1 ", end="")
        continue

    # Print the current value of 'x' plus the count of occurrences of 'i'
    print(x + a[i], end=" ")

    # Push 'i' into the stack 'a[i]' times
    for _ in range(a[i]):
        stack.append(i)

    # Check if the stack is empty
    if len(stack) == 0:
        p = 1  # Set 'p' to 1 if the stack is empty
    else:
        # Update 'x' by adding 'i' minus the top element of the stack
        x = x + i - stack.pop()  # Pop the top element from the stack

# This code is contributed by shivamgupta0987654321

Output
1 1 0 -1 







Time Complexity: O(N), where N is the size of input array arr[].
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads