📌  相关文章
📜  具有最大 MEX 前缀数组和的数组的排列计数

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

具有最大 MEX 前缀数组和的数组的排列计数

给定一个大小为N的数组 arr ,任务是找到其排列的数量,使得其前缀数组的 MEX 之和最大。

注:一组整数的 MEX 定义为不属于该组的最小非负整数。

例子:

方法:

最佳想法是基于以下观察:当所有不同元素按递增顺序排列并且重复元素出现在数组末尾(如 0、1、2、3、 ……)。一旦这种连续性中断,其余的 MEX 在此之后保持不变。例如,在 {0, 1, 2, 2, 5, 6} 中,前缀数组的 MEX 是 {1, 2, 3, 3, 3, 3},其中连续性在索引 3 处中断。

现在,要找到具有最大 MEX 和的所有排列的计数,请将元素的频率存储在映射中。在最大 MEX 前缀数组中,第一个位置始终由 0 填充,然后第二个由 1 填充,然后第三个由 2 填充,依此类推。因此,尝试用可用的选择数量填充这些,一旦达到连续性中断的点,该点之后所有排列的 MEX 是相同的,之后的元素可以以任何可能的排列排列。现在为了更好地理解它,假设数组中存在 0 到 Y 个数字,然后连续性中断,之后出现 K 个更多元素。那么具有最大 MEX 总和的排列计数为:

现在,在 {0, 1, 2, 2, 5, 6} 的情况下,具有其前缀数组的最大 MEX 和的数组可以:

  • 仅在索引 0 处包含 0,因此第一个索引的选择数为 1。
  • 仅在索引 1 处包含 1,因此此处的选择数为 1。
  • 包含两个 2 中的任何一个,所以这里的选择数是 2。
  • 现在,在此之后连续性中断,之后的元素可以按任何顺序排列:
    • 所以,这一点之后的选择总数是P(3, 3)            , IE 3!=6            .
  • 现在,所有排列的最终数量是1*1*2*6=12            .

请按照以下步骤解决问题:

  1. 声明一个地图mp来存储元素的频率。
  2. 现在创建一个变量cnt来跟踪元素右侧的元素,并用 N 初始化它,即存在的元素总数。
  3. 还要声明一个变量ans来存储答案并将其初始化为 1。
  4. 现在开始从 0 迭代到给定数组的大小,即从 i = 0 到 i < n :
    • 如果 mp[i] != 0,这意味着在此之前连续性占优势,并且要考虑所有可能的选择(即 mp[i])。因此, ans 将变为ans=ans*mp[i]并将 cnt 减 1 以使元素出现在下一个元素的右侧。
    • 如果 mp[i] == 0,这意味着这里的连续性中断并且在此之后的元素可以以任何可能的排列排列。因此,在这里打破循环并考虑该点右侧存在的元素的所有可能排列,即cnt的阶乘。
  5. 根据以上观察打印答案。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
 
using namespace std;
 
// To calculate the factorial
int factorial(int n)
{
    int res = 1, i;
    for (i = 2; i <= n; i++) {
        res *= i;
    }
    return res;
}
 
// To return the number of permutations of
// an array with maximum MEXs sum of prefix array
int countPermutations(int ar[], int n)
{
 
    // Map to store the frequency of each element
    unordered_map mp;
 
    int ans = 1, cnt = n;
 
    for (int i = 0; i < n; i++) {
        mp[ar[i]]++;
    }
 
    // Running a loop from i=0 to i


Java
// java program for the above approach
import java.util.*;
class GFG
{
 
// To calculate the factorial
static int factorial(int n)
{
    int res = 1, i;
    for (i = 2; i <= n; i++) {
        res *= i;
    }
    return res;
}
 
// To return the number of permutations of
// an array with maximum MEXs sum of prefix array
static int countPermutations(int[] ar, int n)
{
 
    // Map to store the frequency of each element
    Map mp= new HashMap();
    int ans = 1, cnt = n, i;
 
    for (i = 0; i < n; i++) {
        if (mp.containsKey(ar[i]))
        {
            mp.put(ar[i],mp.get(ar[i])+1);
        }
        else
        {
            mp.put(ar[i], 1);
        }
    }
 
    // Running a loop from i=0 to i


Python3
# Python Program to implement
# the above approach
 
# To calculate the factorial
def factorial(n):
    res = 1
    for i in range(2, n + 1):
        res *= i
    return res
 
# To return the number of permutations of
# an array with maximum MEXs sum of prefix array
def countPermutations(ar, n):
 
    # Map to store the frequency of each element
    mp = dict()
 
    ans = 1
    cnt = n
 
    for i in range(n):
 
        if (ar[i] in mp):
            mp[ar[i]] += 1
        else:
            mp[ar[i]] = 1
 
    # Running a loop from i=0 to i


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG
{
 
// To calculate the factorial
static int factorial(int n)
{
    int res = 1, i;
    for (i = 2; i <= n; i++) {
        res *= i;
    }
    return res;
}
 
// To return the number of permutations of
// an array with maximum MEXs sum of prefix array
static int countPermutations(int[] ar, int n)
{
 
    // Map to store the frequency of each element
    Dictionary mp = new Dictionary();
 
    int ans = 1, cnt = n, i;
 
    for (i = 0; i < n; i++) {
        if (mp.ContainsKey(ar[i]))
        {
            mp[ar[i]] = mp[ar[i]] + 1;
        }
        else
        {
            mp.Add(ar[i], 1);
        }
    }
 
    // Running a loop from i=0 to i


Javascript


输出
2

时间复杂度: O(N)
辅助空间: O(1)