Given a stream of integers and a window size, calculate the moving average of all integers in the sliding window.
Java Solution
This problem is solved by using a queue.
class MovingAverage { double sum; int size; LinkedList<Integer> list; /** Initialize your data structure here. */ public MovingAverage(int size) { this.list = new LinkedList<>(); this.size = size; } public double next(int val) { sum += val; list.offer(val); if(list.size()<=size){ return sum/list.size(); } sum -= list.poll(); return sum/size; } } |
didn’t work
We can use Circular Buffer and implement it more efficiently.
public class MovingAverage {
private int[] arr;
int ptr, n;
private int sum;
/** Initialize your data structure here. */
public MovingAverage(int size) {
arr = new int[size];
ptr = 0;
sum = 0;
}
public double Next(int val) {
if(n < arr.Length)
n++;
sum = sum – arr[ptr];
sum = sum + val;
arr[ptr] = val;
ptr = (ptr + 1)%(arr.Length);
return (double)sum/n;
}
}
Much more simpler version:
public class MovingAverageInSlidingWIndow {
int windowsize;
Queue queue;
int sum;
public MovingAverageInSlidingWIndow(int windowsize) {
this.windowsize = windowsize;
this.queue = new LinkedList();
this.sum = 0;
}
// finds moving average after inserting item n into data stream
private double findMovingAverage(int n) {
if (queue.size() > windowsize - 1) {
sum = sum - queue.poll();
}
queue.offer(n);
sum = sum + n;
return (double) sum / queue.size();
}
public static void main(String[] args) {
int windowsize = 3;
MovingAverageInSlidingWIndow m = new MovingAverageInSlidingWIndow(windowsize);
for (int i = 1; i < 20; i++) {
System.out.println("After Adding " + i + " to the queue: {" + m.queue.toString() + "}; Average is: " + m.findMovingAverage(i));
}
}
}
We can simply persist the current sum of elements in queue in global variable. Thus, reducing the computation in next() method.
public class MovingAverage {
LinkedList queue;
int size;
int sum = 0; // holds sum the queue
/** Initialize your data structure here. */
public MovingAverage(int size) {
this.queue = new LinkedList();
this.size = size;
}
public double next(int val) {
queue.offer(val);
sum += val;
if(queue.size()>this.size){
sum -= queue.poll();
}
return (double)sum/queue.size();
}
}