一、问题描述
Given a stream of integers and a window size, calculate the moving average of all integers in the sliding window.
For example,
MovingAverage m = new MovingAverage(3); m.next(1) = 1 m.next(10) = (1 + 10) / 2 m.next(3) = (1 + 10 + 3) / 3 m.next(5) = (10 + 3 + 5) / 3
二、我的思路
数据结构:用一个int size存window大小,用一个ArrayList存数据流。
算法:当数据流长度小于window大小时,有多少加多少;当数据流大于window大小时,以window大小为限制。
class MovingAverage {
/** Initialize your data structure here. */
private int size = 0;
private ArrayList<Integer> list = new ArrayList<Integer>();
public MovingAverage(int size) {
this.size = size;
}
public double next(int val) {
if(this.size == 0){
return 0;
}
this.list.add(val);
double sum = 0;
for(int i = this.list.size()-1; i >= Math.max(0, this.list.size()-this.size); i --){
sum += this.list.get(i);
}
return sum/Math.min(this.size, this.list.size());
}
}
/**
* Your MovingAverage object will be instantiated and called as such:
* MovingAverage obj = new MovingAverage(size);
* double param_1 = obj.next(val);
*/
三、淫奇技巧
看了discuss以后,发现即使这么简单的题目,还是很能看出差距的!!
1)
public class MovingAverage {
private int [] window;
private int n, insert;
private long sum;
/** Initialize your data structure here. */
public MovingAverage(int size) {
window = new int[size];
insert = 0;
sum = 0;
}
public double next(int val) {
if (n < window.length) n++;
sum -= window[insert];
sum += val;
window[insert] = val;
insert = (insert + 1) % window.length;
return (double)sum / n;
}
}
O(1)的方法。超级巧妙
用了一个数组作为window;n记录分母,insert记录数据流长度。通过把insert对windowSize求余得到要替换出局的数字和新数字存放的位置!!
2) 依然O(1)
public class MovingAverage {
private double previousSum = 0.0;
private int maxSize;
private Queue<Integer> currentWindow;
public MovingAverage(int size) {
currentWindow = new LinkedList<Integer>();
maxSize = size;
}
public double next(int val) {
if (currentWindow.size() == maxSize)
{
previousSum -= currentWindow.remove();
}
previousSum += val;
currentWindow.add(val);
return previousSum / currentWindow.size();
}}
巧妙的用了Queue这种数据结构维护window里的数据,同时也用了一个变量记录sum,非常简洁!
四、知识点
Queue<Integer> queue = new LinkedList<Integer>();
另外还有余数的神奇作用~
五、碎碎念
虽然题目简单,但是仍然能看出差距好大啊啊啊!!
谷歌电面在即,继续加油!每天都要比昨天的自己好一点~
It‘s time to test how bad I want it!