剑指 Offer II 041. 滑动窗口的平均值
题目描述
-
给定一个整数数据流和一个窗口大小,根据该滑动窗口的大小,计算滑动窗口里所有数字的平均值。
实现
MovingAverage
类:MovingAverage(int size)
用窗口大小size
初始化对象。double next(int val)
成员函数next
每次调用的时候都会往滑动窗口增加一个整数,请计算并返回数据流- 最后
size
个值的移动平均值,即滑动窗口里所有数字的平均值。
算法分析
- 创建一个窗口大小的环形队列,将数据流大小保存环形队列中,并记录元素的个数
- 当队列满时,就将队列头的元素取出来,再将新的数据放进去
- 每次请求都返回元素的和和元素的个数,方便求解
代码实现
class MovingAverage {
Queue queue;
/** Initialize your data structure here. */
public MovingAverage(int size) {
queue = new Queue(size);
}
public double next(int val) {
if (queue.isFull()){
queue.get();
queue.add(val);
}else {
queue.add(val);
}
double sum = queue.sum();
double result = sum / queue.size;
return result;
}
class Queue{
int values[];
int maxSize;
int size;
int front;
int rear;
Queue(int maxSize){
this.maxSize = maxSize + 1;
values = new int[this.maxSize];
front = 0;
rear = 0;
size = 0;
}
//入队列
void add(int v){
if (isFull()){
throw new RuntimeException("队列已满");
}else{
values[rear++] = v;
rear = (rear) % maxSize;
size++;
}
}
//出队列
int get(){
if (isEmpty()){
throw new RuntimeException("队列为空");
}
int result = values[front];
front = (front + 1) % maxSize;
size--;
return result;
}
//判空
boolean isEmpty(){
if (front == rear){
return true;
}else{
return false;
}
}
//判满
boolean isFull(){
if ((rear + 1) % maxSize == front){
return true;
}else{
return false;
}
}
//求和
double sum(){
double result = 0;
for (int i = front; i < front + size; i++) {
result += values[i % maxSize];
}
return result;
}
}
}
/**
* Your MovingAverage object will be instantiated and called as such:
* MovingAverage obj = new MovingAverage(size);
* double param_1 = obj.next(val);
*/
涉及知识点
- 环形队列
- 数组
- 链表