📌  相关文章
📜  在流中查找前 k 个(或最频繁的)数字

📅  最后修改于: 2021-10-28 01:33:23             🧑  作者: Mango

给定一个由 n 个数字组成的数组。您的任务是从数组中读取数字,并在每次读取新数字时将最多 K 个数字保留在顶部(根据它们的下降频率)。当输入流包含 k 个不同的元素时,我们基本上需要打印按频率排序的前 k 个数字,否则需要打印所有按频率排序的不同元素。
例子:

方法:这个想法是存储具有最大频率的前 k 个元素。可以使用向量或数组来存储它们。为了跟踪元素的频率,创建了一个 HashMap 来存储元素频率对。给定一个数字流,当一个新元素出现在流中时,更新该元素在 HashMap 中的频率,并将该元素放在 K 个数字列表的末尾(总共 k+1 个元素),现在比较列表中的相邻元素并如果高频元素存储在它旁边,则交换。
算法:

  1. 创建一个 Hashmap hm和一个长度为k + 1的数组。
  2. 从头到尾遍历输入数组。
  3. 在数组的第 k+1 个位置插入元素,更新该元素在 HashMap 中的频率。
  4. 现在,从头到尾遍历临时数组 – 1
  5. 对于非常元素,如果频率较高的元素存储在它旁边,则比较频率和交换,如果频率相同,则交换是下一个元素更大。
  6. 在原始数组的每次遍历中打印前 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 现场工作专业课程学生竞争性编程现场课程