是否有特定的算法允许我在小/中等大小的滑动窗口上保持最小/最大值(典型大小为600,所有元素都是整数)?窗口实际上是流中的最后N个观察值。所以,我添加了一个新观察并删除了每个时间单位的最老观察,所以我想保持最后和最大值超过最后N个观察点。
这与Sliding window minimum algorithm中所述的问题不同,因为我没有维护整个数据,因此基于"索引的"解决方案不适用于此处。此外,我的输入数据本身将是一个圆形数组。
堆可能效果不好:我不会删除/弹出Min / Max元素,但是最旧的元素,这将首先破坏堆的目的。
log(n)基于复杂性的结构(如红黑树)可以正常工作,而splay树可能更适合我所拥有的数据类型,但它们有点过分杀戮对于我要处理的大小?
答案 0 :(得分:0)
找到最大输入数据流的问题的解决方案托管在下面的链接上,您可以轻松调整它以找到Min。
输入流的大小并不重要,可以是无限的。该算法以分摊常数O(1)复杂度执行。
答案 1 :(得分:0)
这是java中的代码
import java.io.*;
import java.util.*;
public class MinInwindow {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int arr[] = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
int k = sc.nextInt();
printMinInWindow(arr, n, k);
}
static void printMinInWindow(int[] arr, int n, int k) {
int start = 0, last = 0;
ArrayList<Integer> list = new ArrayList<Integer>(k);
while (last < n) {
int val = arr[last];
if (last < k) {
list = addNewINtoList(list, val);
last++;
} else {
//print minimum from window
System.out.print(list.get(0) + " ");
int startValue = arr[start];
start++;
list = removefromListIfAvailable(list, startValue);
list = addNewINtoList(list, val);
last++;
}
}
System.out.println(list.get(0) + " ");
}
static ArrayList<Integer> addNewINtoList(ArrayList<Integer> list, int val) {
if (list.isEmpty()) {
list.add(val);
} else {
int size = list.size();
while (size > 0 && list.get(size - 1) > val) {
list.remove(size - 1);
size--;
}
list.add(val);
}
return list;
}
static ArrayList<Integer> removefromListIfAvailable(ArrayList<Integer> list, int val) {
if (list.isEmpty()) {
return list;
}
int startValue = list.get(0);
if (startValue == val) {
list.remove(0);
}
return list;
}
}