📜  查找流中第 K 个最大元素的Java程序

📅  最后修改于: 2022-05-13 01:55:34.133000             🧑  作者: Mango

查找流中第 K 个最大元素的Java程序

给定一个无限的整数流,在任何时间点找到第 k 个最大的元素。
例子:

Input:
stream[] = {10, 20, 11, 70, 50, 40, 100, 5, ...}
k = 3

Output:    {_,   _, 10, 11, 20, 40, 50,  50, ...}

允许的额外空间是 O(k)。

我们在以下文章中讨论了在数组中查找第 k 个最大元素的不同方法。
未排序数组中的第 K 个最小/最大元素 |设置 1
未排序数组中的第 K 个最小/最大元素 |第 2 组(预期线性时间)
未排序数组中的第 K 个最小/最大元素 |第 3 组(最坏情况线性时间)
这里我们有一个流而不是整个数组,我们只允许存储 k 个元素。

一个简单的解决方案是保留一个大小为 k 的数组。这个想法是保持数组排序,以便可以在 O(1) 时间内找到第 k 个最大元素(如果数组按升序排序,我们只需要返回数组的第一个元素)
如何处理流的新元素?
对于流中的每个新元素,检查新元素是否小于当前第 k 个最大元素。如果是,则忽略它。如果否,则从数组中删除最小元素并按排序顺序插入新元素。处理一个新元素的时间复杂度是 O(k)。

更好的解决方案是使用大小为 k 的自平衡二叉搜索树。第 k 个最大的元素可以在 O(Logk) 时间内找到。
如何处理流的新元素?
对于流中的每个新元素,检查新元素是否小于当前第 k 个最大元素。如果是,则忽略它。如果否,则从树中删除最小元素并插入新元素。处理一个新元素的时间复杂度是 O(Logk)。

一个有效的解决方案是使用大小为 k 的 Min Heap 来存储流的 k 个最大元素。第 k 个最大的元素始终位于根节点,并且可以在 O(1) 时间内找到。
如何处理流的新元素?
将新元素与堆根进行比较。如果新元素较小,则忽略它。否则用新元素替换 root 并调用 heapify 作为修改堆的根。找到第 k 个最大元素的时间复杂度是 O(Logk)。

Java
// Java program for the above approach
import java.io.*;
import java.util.*;
  
class GFG {
    
  /*
  using min heap DS
  
  how data are stored in min Heap DS
         1
       2   3
  if k==3 , then top element of heap
  itself the kth largest largest element
  
  */
  static PriorityQueue min;
  static int k;
  
  static List getAllKthNumber(int arr[])
  {
      
    // list to store kth largest number
    List list = new ArrayList<>();
  
    // one by one adding values to the min heap
    for (int val : arr) {
  
      // if the heap size is less than k , we add to
      // the heap
      if (min.size() < k)
        min.add(val);
  
      /*
      otherwise ,
      first we  compare the current value with the
      min heap TOP value
  
      if TOP val > current element , no need to
      remove TOP , bocause it will be the largest kth
      element anyhow
  
      else  we need to update the kth largest element
      by removing the top lowest element
      */
  
      else {
        if (val > min.peek()) {
          min.poll();
          min.add(val);
        }
      }
  
      // if heap size >=k we add 
      // kth largest element
      // otherwise -1
  
      if (min.size() >= k)
        list.add(min.peek());
      else
        list.add(-1);
    }
    return list;
  }
  
  // Driver Code
  public static void main(String[] args)
  {
    min = new PriorityQueue<>();
  
    k = 4;
  
    int arr[] = { 1, 2, 3, 4, 5, 6 };
  
    List res = getAllKthNumber(arr);
  
    for (int x : res)
      System.out.print(x + " ");
  }
  
    // This code is Contributed by Pradeep Mondal P
}


输出:

K is 3
Enter next element of stream 23
Enter next element of stream 10
Enter next element of stream 15
K'th largest element is 10
Enter next element of stream 70
K'th largest element is 15
Enter next element of stream 5
K'th largest element is 15
Enter next element of stream 80
K'th largest element is 23
Enter next element of stream 100
K'th largest element is 70
Enter next element of stream
CTRL + C pressed

有关更多详细信息,请参阅有关流中第 K 个最大元素的完整文章!