📌  相关文章
📜  唯一三元组的最大数量,以使每个元素仅被选择一次

📅  最后修改于: 2021-05-14 00:30:36             🧑  作者: Mango

给定大小,N的阵列ARR []。找到可以使用数组元素制作的三元组的最大数量,以使每个三元组中的所有元素都不同。打印最大可能的三元组数量以及三元组列表。
注意:数组的每个元素只能属于1个三元组。
例子:

天真的方法:这个想法是运行三个嵌套循环以生成所有三元组,对于每个三元组,检查它们是否成对不同,并检查数组的每个元素是否恰好属于1个三元组。
时间复杂度: O(N 3 )
辅助空间: O(1)
高效进场:可以解决贪婪进场问题,并保持服用三联症的频率最高。步骤如下:

  • 将所有数字的频率存储在地图中。
  • 设置一个最大优先级队列ans以在其中存储对,其中对中的第一个元素是某个元素的频率,而对中的第二个元素是元素本身。
  • 现在,从优先级队列中重复提取前3个元素,使用这3个元素制作三元组,将其频率降低1,然后再次使用大于0的频率将元素插入优先级队列。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function that finds maximum number
// of triplets with different elements
void findTriplets(int ar[], int n)
{
 
    // Map M will store the frequency
    // of each element in the array
    unordered_map mp;
 
    for (int x = 0; x < n; x++)
        mp[ar[x]]++;
 
    // Priority queue of pairs
    // {frequency, value}
    priority_queue > pq;
 
    for (auto& pa : mp)
        pq.push({ pa.second, pa.first });
 
    // ans will store possible triplets
    vector > ans;
 
    while (pq.size() >= 3) {
 
        // Extract top 3 elements
        pair ar[3];
        for (int x = 0; x < 3; x++) {
            ar[x] = pq.top();
            pq.pop();
        }
 
        // Make a triplet
        ans.push_back({ ar[0].second,
                        ar[1].second,
                        ar[2].second });
 
        // Decrease frequency and push
        // back into priority queue if
        // non-zero frequency
        for (int x = 0; x < 3; x++) {
            ar[x].first--;
            if (ar[x].first)
                pq.push(ar[x]);
        }
    }
 
    // Print the triplets
    cout << "Maximum number of "
         << "possible triples: ";
    cout << ans.size() << endl;
 
    for (auto& pa : ans) {
 
        // Print the triplets
        for (int v : pa)
            cout << v << " ";
        cout << endl;
    }
}
 
// Driver Code
int main()
{
    // Given array arr[]
    int arr[] = { 2, 2, 3, 3, 4, 4, 4, 4, 5 };
 
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    findTriplets(arr, n);
    return 0;
}


Java
// Java program for the
// above approach
import java.util.*;
import java.lang.*;
class GFG{
 
static class pair
{
  int first, second;
  pair(int first, int second)
  {
    this.first = first;
    this.second = second;
  }
}
 
// Function that finds maximum
// number of triplets with
// different elements
static void findTriplets(int arr[],
                         int n)
{
  // Map M will store the frequency
  // of each element in the array
  Map mp = new HashMap<>();
 
  for (int x = 0; x < n; x++)
    mp.put(arr[x],
    mp.getOrDefault(arr[x], 0) + 1);
 
  // Priority queue of pairs
  // {frequency, value}
  PriorityQueue pq =
          new PriorityQueue<>((a, b) ->
                               a.first -
                               b.first);
 
  for (Map.Entry k : mp.entrySet())
    pq.add(new pair(k.getValue(),
                    k.getKey()));
 
  // ans will store possible
  // triplets
  ArrayList > ans =
                 new ArrayList<>();
 
  while (pq.size() >= 3)
  {
    // Extract top 3 elements
    pair[] ar = new pair[3];
    for (int x = 0; x < 3; x++)
    {
      ar[x] = pq.peek();
      pq.poll();
    }
 
    // Make a triplet
    ans.add(Arrays.asList(ar[0].second,
                          ar[1].second,
                          ar[2].second));
 
    // Decrease frequency and push
    // back into priority queue if
    // non-zero frequency
    for (int x = 0; x < 3; x++)
    {
      ar[x].first--;
      if (ar[x].first != 0)
        pq.add(ar[x]);
    }
  }
 
  // Print the triplets
  System.out.println("Maximum number of " +
                     "possible triples: " +
                      ans.size());
 
  for (List pa : ans)
  {
    // Print the triplets
    for (Integer v : pa)
      System.out.print(v + " ");
 
    System.out.println();
  }
}
 
// Driver function
public static void main(String[] args)
{
  // Given array arr[]
  int arr[] = {2, 2, 3, 3, 4,
               4, 4, 4, 5};
 
  int n = arr.length;
 
  // Function Call
  findTriplets(arr, n);
}
}
 
// This code is contributed by offbeat


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
 
  // Function that finds maximum number
  // of triplets with different elements
  static void findTriplets(int[] arr, int n)
  {
 
    // Map M will store the frequency
    // of each element in the array
    Dictionary mp = new Dictionary();
    for (int x = 0; x < n; x++)
    {
      if(mp.ContainsKey(arr[x]))
      {
        mp[arr[x]]++;
      }
      else
      {
        mp[arr[x]] = 1;
      }
    }
 
    // Priority queue of pairs
    // {frequency, value}
    List > pq = new List>();
    int cnt = 0;
    foreach(KeyValuePair pa in mp)
      pq.Add(new Tuple(pa.Value, pa.Key));
 
    // ans will store possible triplets
    List> ans = new List>();
    pq.Sort();
    pq.Reverse();
    while (pq.Count >= 3)
    {
 
      // Extract top 3 elements
      Tuple[] ar = new Tuple[3];
      for (int x = 0; x < 3; x++)
      {
        ar[x] = pq[0];
        pq.RemoveAt(0);
      }
      ans.Add(new List());
      ans[cnt].Add(ar[0].Item2);
      ans[cnt].Add(ar[1].Item2);
      ans[cnt].Add(ar[2].Item2);
 
      // Decrease frequency and push
      // back into priority queue if
      // non-zero frequency
      for (int x = 0; x < 3; x++)
      {
        ar[x] = new Tuple(ar[x].Item1 - 1, ar[x].Item2);
        if (ar[x].Item1 != 0)
        {
          pq.Add(ar[x]);
          pq.Sort();
          pq.Reverse();
        }
      }
      cnt++;
    }
 
    // Print the triplets
    Console.Write("Maximum number of possible triples: ");
    Console.WriteLine(ans.Count);
    foreach(List pa in ans)
    {
 
      // Print the triplets
      foreach(int v in pa)
        Console.Write(v + " ");
      Console.WriteLine();
    }
  }
 
  // Driver code
  static void Main()
  {
 
    // Given array arr[]
    int[] arr = { 2, 2, 3, 3, 4, 4, 4, 4, 5 };
 
    int n = arr.Length;
 
    // Function Call
    findTriplets(arr, n);
  }
}
 
// This code is contributed by divyeshrabadiya07.


输出:
Maximum number of possible triples: 2
4 3 2 
4 5 3

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