给定一个大小为N的数组arr[] 。找出可以使用数组元素组成的最大三元组数,使得每个三元组中的所有元素都不同。打印可能的三元组的最大数量以及三元组的列表。
注意:数组的每个元素只能属于 1 个三元组。
例子:
Input: arr[] = {2, 2, 3, 3, 4, 4, 4, 4, 5}
Output:
Maximum number of possible triples : 2
2 3 4
3 4 5
Explanation:
We can form at most 2 triples using the given array such that each triple contains different elements.
Input: arr[] = {1, 2, 3, 4, 5, 6, 7 }
Output:
Maximum number of possible triples : 2
5 6 7
2 3 4
Explanation:
We can form at most 2 triples using the given array such that each triple contains different elements.
朴素的方法:这个想法是运行三个嵌套循环来生成所有三元组,对于每个三元组,检查它们是否成对不同,并检查数组的每个元素是否恰好属于 1 个三元组。
时间复杂度: O(N 3 )
辅助空间: O(1)
Efficient Approach:这个问题可以解决Greedy Approach并继续取具有最大频率的三元组。以下是步骤:
- 将所有数字的频率存储在 Map 中。
- 使最高优先级队列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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live