【问题标题】:Find the max element in all the contiguous subarray of size K using only queue仅使用队列在所有大小为 K 的连续子数组中查找最大元素
【发布时间】:2021-07-08 08:30:46
【问题描述】:

给出一个数组 A 和一个整数 K。我们必须在 JAVA 中使用仅队列在所有大小为 K 的连续子数组中找到最大元素。

例如:

Input:
7 3
12 1 78 90 57 89 56

Output:
78 90 90 90 89

如何在 Java 中使用 only queue 解决这个问题?

【问题讨论】:

  • 给出了一个数组和一个整数,...,仅使用队列解决它。什么队列?你尝试了什么,你在哪里卡住了?请选择一种语言
  • 我可以用双端队列来解决这个问题……但我正在尝试只使用队列来解决它。
  • 您需要一个函数来返回给定队列中的最大元素。然后创建一个队列并用列表的前 K 个元素填充它。打印最大值后(借助最初提到的函数),丢弃第一个元素并添加一个新元素。重复直到没有新元素为止。

标签: java algorithm data-structures queue


【解决方案1】:

您可以使用Sliding Window 技术来查找大小为K 的所有连续子数组中的最大元素。
我们需要为此使用PriorityQueue,以便我们可以在恒定时间内检索特定窗口的最大元素。 首先,将所有第一个 K 元素添加到队列中并返回第一个最大值,然后通过添加新的头部并移除窗口的尾部来迭代大小为 K 的其余窗口/子数组。
并且在每次迭代中不断返回当前窗口的peek(最大值)。
这是一个实现:

PriorityQueue<Integer> queue = 
new PriorityQueue<>(Collections.reverseOrder());
 
for (int i=0; i < K; i++)
    queue.add(arr[i]);
 
System.out.println(queue.peek()); // maximum element among first `K` elements
 
// Rest of the windows of size `K`
for (int i=K; i < N; i++)
{
    queue.remove(arr[i - K]); // first element from front
    queue.add(arr[i]);       // adding current element
    System.out.println(queue.peek()); // maximum element in current window
}

【讨论】:

  • 这要求整数是唯一的吗?
  • @Surt 不,它也可以完美地处理具有重复项的数组。
  • PriorityQueue.remove(Object o) 需要线性(队列大小)时间,即O(K)。这并不比扫描窗口中的最大元素更好。
  • @user58697 是的,它是O(N*K),但请再次阅读问题。 OP 已经严格提到他想要一种仅使用 queue 的方法。据我所知,如果我们使用队列,这是我们可以实现的最佳时间复杂度。如果我们使用他已经知道的deque,则 O(N) 是可能的。如果您有使用队列的更有效方法,请分享您的想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-20
  • 2021-04-11
  • 1970-01-01
  • 2015-11-09
  • 2018-09-19
  • 1970-01-01
  • 2016-12-29
相关资源
最近更新 更多