给定一个由 n 个数字组成的数组。您的任务是从数组中读取数字,并在每次读取新数字时将最多 K 个数字保留在顶部(根据它们的下降频率)。当输入流包含 k 个不同的元素时,我们基本上需要打印按频率排序的前 k 个数字,否则需要打印所有按频率排序的不同元素。
例子:
Input : arr[] = {5, 2, 1, 3, 2}
k = 4
Output : 5 2 5 1 2 5 1 2 3 5 2 1 3 5
Explanation:
- After reading 5, there is only one element 5 whose frequency is max till now.
so print 5. - After reading 2, we will have two elements 2 and 5 with the same frequency.
As 2, is smaller than 5 but their frequency is the same so we will print 2 5. - After reading 1, we will have 3 elements 1, 2 and 5 with the same frequency,
so print 1 2 5. - Similarly after reading 3, print 1 2 3 5
- After reading last element 2 since 2 has already occurred so we have now a
frequency of 2 as 2. So we keep 2 at the top and then rest of the element
with the same frequency in sorted order. So print, 2 1 3 5.
Input : arr[] = {5, 2, 1, 3, 4}
k = 4
Output : 5 2 5 1 2 5 1 2 3 5 1 2 3 4
Explanation:
- After reading 5, there is only one element 5 whose frequency is max till now.
so print 5. - After reading 2, we will have two elements 2 and 5 with the same frequency.
As 2, is smaller than 5 but their frequency is the same so we will print 2 5. - After reading 1, we will have 3 elements 1, 2 and 5 with the same frequency,
so print 1 2 5.
Similarly after reading 3, print 1 2 3 5 - After reading last element 4, All the elements have same frequency
So print, 1 2 3 4.
方法:这个想法是存储具有最大频率的前 k 个元素。可以使用向量或数组来存储它们。为了跟踪元素的频率,创建了一个 HashMap 来存储元素频率对。给定一个数字流,当一个新元素出现在流中时,更新该元素在 HashMap 中的频率,并将该元素放在 K 个数字列表的末尾(总共 k+1 个元素),现在比较列表中的相邻元素并如果高频元素存储在它旁边,则交换。
算法:
- 创建一个 Hashmap hm和一个长度为k + 1的数组。
- 从头到尾遍历输入数组。
- 在数组的第 k+1 个位置插入元素,更新该元素在 HashMap 中的频率。
- 现在,从头到尾遍历临时数组 – 1
- 对于非常元素,如果频率较高的元素存储在它旁边,则比较频率和交换,如果频率相同,则交换是下一个元素更大。
- 在原始数组的每次遍历中打印前 k 个元素。
执行:
C++
// C++ program to find top k elements in a stream
#include
using namespace std;
// Function to print top k numbers
void kTop(int a[], int n, int k)
{
// vector of size k+1 to store elements
vector top(k + 1);
// array to keep track of frequency
unordered_map freq;
// iterate till the end of stream
for (int m = 0; m < n; m++) {
// increase the frequency
freq[a[m]]++;
// store that element in top vector
top[k] = a[m];
// search in top vector for same element
auto it = find(top.begin(), top.end() - 1, a[m]);
// iterate from the position of element to zero
for (int i = distance(top.begin(), it) - 1; i >= 0; --i) {
// compare the frequency and swap if higher
// frequency element is stored next to it
if (freq[top[i]] < freq[top[i + 1]])
swap(top[i], top[i + 1]);
// if frequency is same compare the elements
// and swap if next element is high
else if ((freq[top[i]] == freq[top[i + 1]])
&& (top[i] > top[i + 1]))
swap(top[i], top[i + 1]);
else
break;
}
// print top k elements
for (int i = 0; i < k && top[i] != 0; ++i)
cout << top[i] << ' ';
}
cout << endl;
}
// Driver program to test above function
int main()
{
int k = 4;
int arr[] = { 5, 2, 1, 3, 2 };
int n = sizeof(arr) / sizeof(arr[0]);
kTop(arr, n, k);
return 0;
}
Java
import java.io.*;
import java.util.*;
class GFG {
// function to search in top vector for element
static int find(int[] arr, int ele)
{
for (int i = 0; i < arr.length; i++)
if (arr[i] == ele)
return i;
return -1;
}
// Function to print top k numbers
static void kTop(int[] a, int n, int k)
{
// vector of size k+1 to store elements
int[] top = new int[k + 1];
// array to keep track of frequency
HashMap freq = new HashMap<>();
for (int i = 0; i < k + 1; i++)
freq.put(i, 0);
// iterate till the end of stream
for (int m = 0; m < n; m++) {
// increase the frequency
if (freq.containsKey(a[m]))
freq.put(a[m], freq.get(a[m]) + 1);
else
freq.put(a[m], 1);
// store that element in top vector
top[k] = a[m];
// search in top vector for same element
int i = find(top, a[m]);
i -= 1;
// iterate from the position of element to zero
while (i >= 0) {
// compare the frequency and swap if higher
// frequency element is stored next to it
if (freq.get(top[i]) < freq.get(top[i + 1])) {
int temp = top[i];
top[i] = top[i + 1];
top[i + 1] = temp;
}
// if frequency is same compare the elements
// and swap if next element is high
else if ((freq.get(top[i]) == freq.get(top[i + 1])) && (top[i] > top[i + 1])) {
int temp = top[i];
top[i] = top[i + 1];
top[i + 1] = temp;
}
else
break;
i -= 1;
}
// print top k elements
for (int j = 0; j < k && top[j] != 0; ++j)
System.out.print(top[j] + " ");
}
System.out.println();
}
// Driver program to test above function
public static void main(String args[])
{
int k = 4;
int[] arr = { 5, 2, 1, 3, 2 };
int n = arr.length;
kTop(arr, n, k);
}
}
// This code is contributed by rachana soma
Python
# Python program to find top k elements in a stream
# Function to print top k numbers
def kTop(a, n, k):
# list of size k + 1 to store elements
top = [0 for i in range(k + 1)]
# dictionary to keep track of frequency
freq = {i:0 for i in range(k + 1)}
# iterate till the end of stream
for m in range(n):
# increase the frequency
if a[m] in freq.keys():
freq[a[m]] += 1
else:
freq[a[m]] = 1
# store that element in top vector
top[k] = a[m]
i = top.index(a[m])
i -= 1
while i >= 0:
# compare the frequency and swap if higher
# frequency element is stored next to it
if (freq[top[i]] < freq[top[i + 1]]):
t = top[i]
top[i] = top[i + 1]
top[i + 1] = t
# if frequency is same compare the elements
# and swap if next element is high
elif ((freq[top[i]] == freq[top[i + 1]]) and (top[i] > top[i + 1])):
t = top[i]
top[i] = top[i + 1]
top[i + 1] = t
else:
break
i -= 1
# print top k elements
i = 0
while i < k and top[i] != 0:
print top[i],
i += 1
print
# Driver program to test above function
k = 4
arr = [ 5, 2, 1, 3, 2 ]
n = len(arr)
kTop(arr, n, k)
# This code is contributed by Sachin Bisht
C#
// C# program to find top k elements in a stream
using System;
using System.Collections.Generic;
class GFG {
// function to search in top vector for element
static int find(int[] arr, int ele)
{
for (int i = 0; i < arr.Length; i++)
if (arr[i] == ele)
return i;
return -1;
}
// Function to print top k numbers
static void kTop(int[] a, int n, int k)
{
// vector of size k+1 to store elements
int[] top = new int[k + 1];
// array to keep track of frequency
Dictionary
freq = new Dictionary();
for (int i = 0; i < k + 1; i++)
freq.Add(i, 0);
// iterate till the end of stream
for (int m = 0; m < n; m++) {
// increase the frequency
if (freq.ContainsKey(a[m]))
freq[a[m]]++;
else
freq.Add(a[m], 1);
// store that element in top vector
top[k] = a[m];
// search in top vector for same element
int i = find(top, a[m]);
i--;
// iterate from the position of element to zero
while (i >= 0) {
// compare the frequency and swap if higher
// frequency element is stored next to it
if (freq[top[i]] < freq[top[i + 1]]) {
int temp = top[i];
top[i] = top[i + 1];
top[i + 1] = temp;
}
// if frequency is same compare the elements
// and swap if next element is high
else if (freq[top[i]] == freq[top[i + 1]] && top[i] > top[i + 1]) {
int temp = top[i];
top[i] = top[i + 1];
top[i + 1] = temp;
}
else
break;
i--;
}
// print top k elements
for (int j = 0; j < k && top[j] != 0; ++j)
Console.Write(top[j] + " ");
}
Console.WriteLine();
}
// Driver Code
public static void Main(String[] args)
{
int k = 4;
int[] arr = { 5, 2, 1, 3, 2 };
int n = arr.Length;
kTop(arr, n, k);
}
}
// This code is contributed by
// sanjeev2552
Javascript
输出:
5 2 5 1 2 5 1 2 3 5 2 1 3 5
复杂度分析:
- 时间复杂度: O( n * k )。
在每次遍历中,都会遍历大小为 k 的临时数组,因此时间复杂度为 O( n * k )。 - 空间复杂度: O(n)。
将元素存储在 HashMap 中需要 O(n) 空间。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。