📌  相关文章
📜  重新排列数组元素以最大化所有前缀数组的MEX之和

📅  最后修改于: 2021-04-17 16:16:00             🧑  作者: Mango

给定大小为N的数组arr [] ,任务是重新排列数组元素,以使所有前缀数组的MEX之和最大。

注意:序列的MEX是序列中不存在的最小非负数。

例子:

天真的方法:最简单的方法是生成给定数组arr []的所有可能的排列,然后对于每个排列,找到所有前缀数组的MEX值,同时跟踪总的最大值。遍历所有可能的排列后,请打印具有最大值的排列。

时间复杂度: O(N 2 * N!)
辅助空间: O(N)

高效的方法:最佳想法是基于以下观察结果:当所有不同元素以递增顺序排列并且重复项出现在数组末尾时,前缀数组的MEX总和将最大。
请按照以下步骤解决问题:

  • 初始化一个整数向量,例如ans,以存储所需的排列。
  • 以递增顺序对数组arr []进行排序。
  • 遍历数组arr []并将所有不同的元素推入数组ans []
  • 再次遍历数组arr []并将所有其余重复元素推入数组ans []
  • 完成上述步骤后,打印数组ans []

下面是上述方法的实现:

C++
// C++ program for the above appraoch
#include 
using namespace std;
 
// Function to find the maximum sum of
// MEX of prefix arrays for any
// arrangement of the given array
void maximumMex(int arr[], int N)
{
 
    // Stores the final arrangement
    vector ans;
 
    // Sort the array in increasing order
    sort(arr, arr + N);
 
    // Iterate over the array arr[]
    for (int i = 0; i < N; i++) {
        if (i == 0 || arr[i] != arr[i - 1])
            ans.push_back(arr[i]);
    }
 
    // Iterate over the array, arr[]
    // and push the remaining occurrences
    // of the elements into ans[]
    for (int i = 0; i < N; i++) {
        if (i > 0 && arr[i] == arr[i - 1])
            ans.push_back(arr[i]);
    }
 
    // Print the array, ans[]
    for (int i = 0; i < N; i++)
        cout << ans[i] << " ";
}
 
// Driver Code
int main()
{
 
    // Given array
    int arr[] = { 1, 0, 0 };
 
    // Store the size of the array
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    maximumMex(arr, N);
 
    return 0;
}


Java
// Java program for the above appraoch
import java.util.Arrays;  
 
class GFG{
     
// Function to find the maximum sum of
// MEX of prefix arrays for any
// arrangement of the given array
static void maximumMex(int arr[], int N)
{
     
    // Stores the final arrangement
    int ans[] = new int[2 * N];
 
    // Sort the array in increasing order
    Arrays.sort(ans);
    int j = 0;
     
    // Iterate over the array arr[]
    for(int i = 0; i < N; i++)
    {
        if (i == 0 || arr[i] != arr[i - 1])
        {
            j += 1;
            ans[j] = arr[i];
        }
    }
 
    // Iterate over the array, arr[]
    // and push the remaining occurrences
    // of the elements into ans[]
    for(int i = 0; i < N; i++)
    {
        if (i > 0 && arr[i] == arr[i - 1])
        {
            j += 1;
            ans[j] = arr[i];
        }
    }
 
    // Print the array, ans[]
    for(int i = 0; i < N; i++)
        System.out.print(ans[i] + " ");
}
 
// Driver Code
public static void main (String[] args)
{
     
    // Given array
    int arr[] = { 1, 0, 0 };
 
    // Store the size of the array
    int N = arr.length;
 
    // Function Call
    maximumMex(arr, N);
}
}
 
// This code is contributed by AnkThon


Python3
# Python3 program for the above appraoch
 
# Function to find the maximum sum of
# MEX of prefix arrays for any
# arrangement of the given array
def maximumMex(arr, N):
 
    # Stores the final arrangement
    ans = []
 
    # Sort the array in increasing order
    arr = sorted(arr)
 
    # Iterate over the array arr[]
    for i in range(N):
        if (i == 0 or arr[i] != arr[i - 1]):
            ans.append(arr[i])
 
    # Iterate over the array, arr[]
    # and push the remaining occurrences
    # of the elements into ans[]
    for i in range(N):
        if (i > 0 and arr[i] == arr[i - 1]):
            ans.append(arr[i])
 
    # Prthe array, ans[]
    for i in range(N):
        print(ans[i], end = " ")
 
# Driver Code
if __name__ == '__main__':
   
    # Given array
    arr = [1, 0, 0 ]
 
    # Store the size of the array
    N = len(arr)
 
    # Function Call
    maximumMex(arr, N)
 
# This code is contributed by mohit kumar 29.


C#
// C# program for the above appraoch
using System;
 
class GFG{
     
// Function to find the maximum sum of
// MEX of prefix arrays for any
// arrangement of the given array
static void maximumMex(int []arr, int N)
{
     
    // Stores the final arrangement
    int []ans = new int[2 * N];
 
    // Sort the array in increasing order
    Array.Sort(ans);
    int j = 0;
     
    // Iterate over the array arr[]
    for(int i = 0; i < N; i++)
    {
        if (i == 0 || arr[i] != arr[i - 1])
        {
            j += 1;
            ans[j] = arr[i];
        }
    }
 
    // Iterate over the array, arr[]
    // and push the remaining occurrences
    // of the elements into ans[]
    for(int i = 0; i < N; i++)
    {
        if (i > 0 && arr[i] == arr[i - 1])
        {
            j += 1;
            ans[j] = arr[i];
        }
    }
 
    // Print the array, ans[]
    for(int i = 0; i < N; i++)
        Console.Write(ans[i] + " ");
}
 
// Driver Code
public static void Main (string[] args)
{
     
    // Given array
    int []arr = { 1, 0, 0 };
 
    // Store the size of the array
    int N = arr.Length;
 
    // Function Call
    maximumMex(arr, N);
}
}
 
// This code is contributed by AnkThon


输出:
0 1 0

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