我昨天去面试了。我想不出一个编程问题的解决方案,我想在这里得到一些想法。问题是:
我需要在 Java 中实现一个TimeWindowBuffer,它存储用户随着时间的推移不断收到的数字。缓冲区有一个maxBufferSize。用户想知道过去几秒的平均值,一个用户传入的timeWindow(所以这是一个滑动窗口)。我们可以从系统中获取当前时间(例如System.currentTimeMills()
在 Java 中)。TimeWindowBuffer类是这样的:
public class TimeWindowBuffer {
private int maxBufferSize;
private int timeWindow;
public TimwWindowBuffer(int maxBufferSize, int timeWindow) {
this.maxBufferSize = maxBufferSize;
this.timeWindow = timeWindow;
}
public void addValue(long value) {
...
}
public double getAvg() {
...
return average;
}
// other auxiliary methods
}
例子:
比如说,一个用户每秒收到一个号码(用户可能不会以一定的速率收到一个号码),并且想知道过去 5 秒的平均值。
输入:
maxBufferSize = 5, timeWindow = 5 (s)
numbers={-5 4 -8 -8 -8 1 6 1 8 5}
输出(我在这里列出公式来说明,但用户只需要结果):-
5 / 1 (t=1)
(-5 + 4) / 2 (t=2)
(-5 + 4 - 8) / 3 (t=3)
(-5 + 4 - 8 - 8) / 4 (t= 4)
(-5 + 4 - 8 - 8 - 8) / 5 (t=5)
(4 - 8 - 8 - 8 + 1) / 5 (t=6)
(-8 - 8 - 8 + 1 + 6 ) / 5 (t=7)
(-8 - 8 + 1 + 6 + 1) / 5 (t=8)
(-8 + 1 + 6 + 1 + 8) / 5 (t=9)
(1 + 6 + 1 + 8 + 5) / 5 (t=10)
由于没有指定TimeWindowBuffer的数据结构,所以一直在考虑保留一对 value 及其添加的时间。所以我对底层缓冲区的声明是这样的:
private ArrayList<Pair> buffer = new ArrayList<Pair>(maxBufferSize);
在哪里
class Pair {
private long value;
private long time;
...
}
由于 Pair 是按时间顺序添加的,因此我可以对列表进行二进制搜索并计算落入timeWindow的数字的平均值。问题是缓冲区有一个maxBufferSize(尽管 ArrayList 没有),当缓冲区已满时我必须删除最旧的值。而且该值仍然可以满足timeWindow但现在它已取消记录,我永远不会知道它何时到期。
我被困在这里当前。
我不需要直接的答案,但在这里有一些讨论或想法。如果对问题和我的描述有任何混淆,请现在告诉我。