Minimum Increments to reach the given MEX in C++

In C++, there also exists a case in which, the Minimum Excluded (MEX) value in an array is to be found by the minimal number of increments. MEX in general finds the smallest non-negative integer which has no occurrences among the array elements. The final product of the instruction is the filled array having the minimum number of increments possible to contain all non-negative integers up to the given MEX value.

This can be done by conducting sorting and binary search operations. To start with you sort the array. The lastly, you use binary search to get the position of the MEX in the arranges array. The time difference of the found MEX and their positions give you the minimum number of steps that can be counted. This method presents the array construction. At the same time, the method allows MEX criterion to be optimal and having O(N) time complexity.

MEX (Minimum EXcluded):

MEX is the smallest non-negative integer that is not present in the array.

The problem is the increment will keep the array containing integers in the range from 0 up to the specified MEX.

Minimum Increments:

An "increment" is specified here as increasing the value of an array element by 1.

The aim is to find the minimum number of increments needed to accomplish the targeted MEX.

Approach 1: Using Sorting

Output:

Original Array: 1 3 2 5 
Minimum increments required to reach MEX 4: 0

Explanation:

The presented C++ source code solves the issue of determining the least increments required to obtain a predefined MEX (Minimum Excluded) value in the given list. It can do this by sorting the array and finding the minima on each iteration.

  • Sorting the array:

The elements of the original array (nums) are first copied into a new vector (sorted_nums), which is then sorted using sort() to get it ordered in ascending order. Sorting serves as the vital operation in the array element traversal.

  • Tracking Variables:

Two variables are utilized to keep track of the progress through the array and the increments made:

Increments: Set to 0, this variable sums up the number of increments made.

Current_mex: Represents the current MEX for the array value in the iteration, starting with an initial value of zero.

  • Iterating Through the Sorted Array:

The loop iterates through the sorted array (sorted_nums). During each iteration, the code checks the relationship between the current element and the current MEX:

So if the element is equal to the current MEX, it means that we have found the MEX and the code increments current_me[x] to move to the next MEX

Suppose the element exceeds the current MEX; the code increments the current MEX, and the total increments by the absolute difference between the MEX and the element. This is why the array gets filled with consecutive integers at the expense of performance.

  • Handling Remaining MEX Values:

After the array is sorted, the next step is to compare MEX with the consecutive values and fill them. Therefore, it subtracts the last MEX number processed from the specified MEX. This difference is then added to the total increments afterwards.

Return Result:

The Function returns the total compliments, which reflect the lowest number of compliments required to reach the designated MEX.

Example Usage in Main:

The main Function demonstrates the usage of the algorithm by considering a given array (nums) and a predetermined MEX value. It invokes the minIncrementsToMex Function with these arguments and returns the result.

The program displays the original array and the smallest jumps needed to achieve the required MEX. This helps users understand how changes to the array meet the MEX condition.

Complexity Analysis:

The time and space complexity of the presented C++ code can be observed to determine the minimum increment that will bring the MEX to the target value to understand its effectiveness.

Time Complexity:

The time complexity depends on the way of sorting the data. In the C++ Standard Template Library (STL), the function sort has an average time performance of O(n log n), where 'n' represents the input array's size.

Sorting the Array:

The sort operation sorts the array sorted_nums of length 'n'. The complexity of the sorting algorithm is O(n log n).

The algorithm scans through the array once after the sorting. Every iteration contains a constant-time operation, which includes comparisons and increments. Therefore, the total time complexity of this step is O(n).

Handling Remaining MEX Values:

The last step, dealing with the rest of the MEX values, also includes constant-time operations and thus adds O(1) to the overall time complexity.

The total time complexity is dependent on the leading term, that is, the sorting process. Hence, the whole time complexity of the code is O(n log n).

Space ComplexityAnalysis:

The space complexity of the code is affected by the data structures created and used dynamically during the algorithm's execution.

Sorted Array (sorted_nums):

So, the new vector sorted_nums is created to store the sorted version of the original array. This vector's space complexity is O(n), where 'n' is the size of the input array.

Tracking Variables (increments and current_mex):

Two variables (increments and current_mex), which are integers, are used to keep track of the increments and the current MEX. These variables have constant space requirements and contribute O(1) to the space complexity.

Other Local Variables:

The code uses a few other local variables, such as loop counters and temporary variables, which consume constant space and contribute O(1) to the overall space complexity.

The dominant term in space complexity is the space required for the sorted array. Thus, the entire space complexity of the code is O(n).

Approach 2: Using Counting Array

Output:

Original Array: 1 3 2 5 
Minimum increments required to reach MEX 4: 0

Explanation:

The given C++ code is developed to find out the least amount of additions required to obtain a particular MEX element in an array with the help of a counting array approach.

  • Initialization of Counting Array (count):

First, a counting array (count) will be prepared with the size of MEX + 1, with MEX representing the MEX value. This array stores the count of occurrences among all the integers up to the MEX.

  • Counting Occurrences in the Original Array (nums):

The code goes through each element of the original array (nums) and updates the counting array with the number of occurrences of each number. This step guarantees the presence of each int's occurrence count till its associated MEX.

  • Iterating Through the Counting Array:

Two variables are initialized: the text value current_mex is to be used to track the MEX value, and increments for the total number of increments made. Therefore, the counting array is iterated through. For all the indices, the code tries to find whether there is a gap between the current MEX and the index. If a gap implies some integers are missing, then the sequences of increments are made to fill in those gaps. The difference between the existing MEX and the index is added to all increments.

  • Returning Total Increments:

The Function returns the total increment, the minimum number of increments required to reach the MEX in the beginning.

Error Handling:

  • Invalid Input Handling:

The code has a check for invalid inputs. The Function returns -1 if the MEX value specified is a negative number. This indicates that the MEX value is invalid.

  • Example Usage in Main:

The main case shows how to implement the algorithm on an array (nums) with a specified MEX value. This Function is called with these parameters, and the Output is achieved through printing.

Output Display:

The program displays the initial array and the minimum number of operations of the kind increase needed to reach the target MEX. Otherwise, a suitable message is shown if the MEX is not attainable or the input is invalid.

Complexity Analysis:

We can calculate the execution time and memory consumption of the given C++ code to evaluate its performance.

Time Complexity Analysis:

The main factor determining the algorithmic complexity is the iterations over the initial array (nums) and the subsequent iterations over the counting array.

Counting Occurrences in the Original Array:

The innermost loop will iterate through the original array (nums), and its time complexity is O(n), where 'n' is the array's length.

Iterating Through the Counting Array:

In the second loop, the loop variable indexes through the counting array that has a size of MEX + 1. In the worst case, it takes 'MEX' iterations for this loop to run. Therefore, the time complexity of this loop is O(MEX).

This way, the time complexity of the code is O(n + MEX) by merging two steps. The notation 'n' is the dominating term when 'MEX' is much smaller than 'n', which shortens the time complexity to O(n).

Space Complexity Analysis:

The extra data structures created determine the space or the additional memory the algorithm requires.

Counting Array (count):

The space taken by the counting array (count) is O(MEX + 1). It's related to the specific MEX value. Therefore, the space complexity is O(mex).

Tracking Variables (current_mex and increments):

Two integer variables (current_mex and increments) are being used here to track the progress of the array and increments made. These variables are constant space, and the remaining O(1) is for the space complexity.

Other Local Variables:

The code also utilizes a few other local variables like loop counters and temporary variables, which use O(1) constant space and contribute to the overall space complexity.

Approach 3: Using HashSet

Output:

Enter the desired MEX value: 4
Original Array: 1 3 2 5 
Minimum increments required to reach MEX 4: 0

Explanation:

The C++ code presented calculates the least number of increments required to get the desired MEX (Minimum Excluded) value in an array. It does that by leveraging a HashSet data structure, which quickly tracks unique elements in the array and derives the smallest missing non-negative integer.

  • HashSet Initialization:

The processing starts by creating a HashSet called "seen" using C++ STL unordered_set. The HashSet, in this case, is responsible for the storage of unique elements present in the array.

  • Count Occurrences in Original Array:

A loop iterates over the original array (nums arrary), adding each element to the 'seen'. This guarantees that the 'seen' dict will consist of all unique elements from the initial array, facilitating the identification of which integers are already in the array and which are missing.

  • Iterate to Find the MEX:

Having calculated how many times each element is repeated in the original array, a variable named 'mex' is initialized to 0. The purpose is to find out the Minimum EXcluded value, which is the least integer and non-negative, which is not in the array. To check, iteratively, whether a current 'mex' value is present in the HashSet, a while loop is used. If found, 'mex' is increased until a value not inside the array is obtained.

  • Return Total Increments:

When the loop locates the MEX value, the Function returns the total minimizations to attain that MEX. This is derived by finding the difference between the final 'mex' value and the size of the 'seen' HashSet, which holds the number of unique elements in the initial array.

  • User Input for Desired MEX:

The main function asks the user to input the ME value. The 'desiredMex' variable is assigned the entered value. Therefore, the function `minIncrementsToMex` is called after modification with the entrance (nums) and the user's MEX value.

  • Output Display:

The program produces the original array and the minimum updates needed to specify the MEX. It involves a loop to output every element of the original array. The outcome is displayed to the user by stating the minimum number of increases needed to obtain the targeted MEX value.

Complexity Analysis:

The time and space complexity of the provided C++ code can be analyzed to understand its efficiency in terms of resource utilization during execution.

Time Complexity Analysis:

The time complexity of the code is calculated with the operations in the loop to iterate through the original array, update the HashSet and look for the MEX.

HashSet Initialization and Counting Occurrences: Declaration of the unordered_set and iterating over the original array take O(n) time. This is because all the elements in the array must be processed once.

Finding the MEX: The runtime of the while loop that sequentially finds the MEX is dependent on the value of the MEX. In the worst case, when the MEX is larger than the array size, the time complexity is O(mex), where 'mex' is the MEX value we want.

As a whole, the time complexity of the code is ruled by the O(n) term most often, making it O(n + mex) in the worst case.

Space Complexity Analysis:

The space complexity of the program depends on the additional data structures created during the run time.

HashSet (seen): The HashSet 'seen' is utilized to keep track of unique objects met in the original array. At most, if all elements are distinct, the size of HashSet would be 'n', the size of the input array. Consequently, the space complexity of a HashSet is O(n).

Variables (mex): The space usage for variable types like 'mex' is constant, thus contributing O(1) to the space complexity.

User Input: The space occupied for user input is constant and does not depend on the input array's size.

Calculating all these parameters, the time complexity of the program is O(n).

Approach 4: Using Binary Search Algorithm

Another method is based on binary search, which can also be used to find the MEX in a sorted array. This method performs a binary search to check the initial guess, sorts the array and then returns the smallest missing non-negative integer.

Output:

Original Array: 1 3 2 5 
Sorted Array: 1 3 2 5 
Minimum increments required to reach MEX: 0

Explanation:

Using a binary search technique, the C++ code here aims to calculate the minimum incrementations required to attain the stated Minimum Excluded (MEX) value in the given array.

minIncrementsToMex Function:

  • Sort the Array:

First, the Function copies the original array and then sorts it in non-decreasing order by using the sort function from the C++ STL

  • Binary Search for MEX:

It then sets two pointers, 'low' and 'high', to specify the search range in the array. The Function conducts a binary searching until the 'low' pointer is greater than and equal to the 'high' pointer. In each iteration, it calculates the middle index and then compares the values at that index with the index itself. Based on the comparison, it narrows down the search range either to the left or right side, according to the results.

  • Calculate Increments:

After finishing the binary search, the Function identifies the MEX value and calculates the least increment needed to achieve it. The 'mex' variable contains the identified MEX, and the 'increments' stores the result.

  • Main Function:

The showcase function demonstrates the utilization of the minIncrementsToMex Function with an example array. The program shows the original and sorted arrays and the minimum steps needed to obtain the required MEX.

Code Execution:

Sort Original Array: The original array was {1, 3, 2, 5}, and its sorted version is printed.

Binary Search and Calculate Increments: The binary search delivers the index of the MEX in the sorted array, and the MEX value and increments are determined.

Output Display: Lastly, the original and sorted arrays, along with the minimum increments, are printed as a final result.

Complexity Analysis:

Time Complexity Analysis:

Sorting the Array:

The code sorts the input array using the sort function from the C++ STL. Usually, the sorting order is O(n log n), where 'n' stands for the array size.

Binary Search for MEX:

The binary search algorithm is applied to the sorted array to find the MEX value. The binary search runs in O(log n) time, where n is the size of the sorted array. This is the fact that the search space is halved in each iteration until the target value is found.

Finally, sorting is the most important factor in the time complexity. Thus, the time complexity of the code is O(n log n).

Space Complexity Analysis:

Sorted Array (sortedNums):

A new vector sortedNums is initialized to retain the sorted version of the input array. The space complexity of this operation depends on the sorting algorithm chosen. If an in-place sorting algorithm is applied, it has a space complexity of O(1) because it sorts the array in the same memory space. Moreover, the additional memory needed for sorting can be O(n) for the worst case.

Variables (low, high, mid, mex, increments):

These variables are of constant size and add their O(1) to the space complexity.

Input Array (nums):

The input array is preserved, and no extra space is used.

Considering these factors, the worst-case space complexity of the code is O(n) if the extra memory is used for sorting. The space complexity can be O(1) if an in-place sorting algorithm is utilized.