📜  来自 [0, N] 的所有整数都显示为最小正缺失数 (MEX) 的最小操作

📅  最后修改于: 2022-05-13 01:57:09.262000             🧑  作者: Mango

来自 [0, N] 的所有整数都显示为最小正缺失数 (MEX) 的最小操作

给定一个大小为N的数组arr[] ,任务是找到数组上的最小操作,使得在每个操作中,可以选择数组中的任何元素并将其递增1 ,这样对于范围内的所有iMEX都是i [0, n] 。如果对于任何i如果MEX不是i打印-1

例子 :

方法:可以使用散列来解决这个问题来存储元素的频率,堆栈可以用来存储数组中的重复元素。 Hashmap 可用于存储MEX = i的频率,如果i已经存在于 hashmap 中,则增加所有出现的次数并将重复的元素存储在堆栈中,否则如果i的频率为0 ,则它已经是MEX ,所以0操作,现在在堆栈中查找重复出现并将其变为当前i以便对于i+1i不会变为MEX 。请按照以下步骤解决此问题:

  • 初始化一个unordered_map freq[]来存储数组arr[]的频率和一个变量is_possible来跟踪MEX的可能性。
  • 遍历数组arr[]并将频率存储在 hashmap freq 中。
  • 初始化堆栈stk[]向量 ops ,以存储MEX = i的最小操作, prev_cost以存储增加重复元素所需的成本。
  • 如果is_possible == 0 ,则MEX = i是不可能的,所以存储-1
  • 否则将freq[i]+ prev_cost存储在ops中。
    • 如果freq[i]等于0检查堆栈中是否有某个元素将其弹出并将其递增到i并将prev_cost递增到ij并递增freq[i] ,如果堆栈为空则将 is_possible 设置为 false。
    • 否则,如果freq[i]>1将重复推入堆栈stk[]并递减freq[i]
  • 现在打印包含使MEX = i [0, n]的最小操作的向量ops

下面是上述方法的实现。

C++
// C++ program for the above approach
#include 
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 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 stk;
 
    // ops store the minimum
    // operations required for MEX =i
    vector 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


输出
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

时间复杂度: O(N) 其中 N 是数组的大小
辅助空间: O(N)