题目
剑指 Offer II 041.
滑动窗口的平均值
给定一个整数数据流和一个窗口大小,根据该滑动窗口的大小,计算滑动窗口里所有数字的平均值。
实现 MovingAverage
类:
MovingAverage(int size)
用窗口大小 size
初始化对象。
double next(int val)
成员函数 next
每次调用的时候都会往滑动窗口增加一个整数,请计算并返回数据流中最后
size
个值的移动平均值,即滑动窗口里所有数字的平均值。
示例:
输入:
inputs = ["MovingAverage", "next", "next", "next", "next"]
inputs = [[3], [1], [10], [3], [5]]
输出:
[null, 1.0, 5.5, 4.66667, 6.0]
解释:
MovingAverage movingAverage = new MovingAverage(3);
movingAverage.next(1); // 返回 1.0 = 1 / 1
movingAverage.next(10); // 返回 5.5 = (1 + 10) / 2
movingAverage.next(3); // 返回 4.66667 = (1 + 10 + 3) / 3
movingAverage.next(5); // 返回 6.0 = (10 + 3 + 5) / 3
提示:
1 <= size <= 1000
- \(-10^{5} <= val <=
10^{5}\)
- 最多调用
next
方法 \(10^{4}\) 次
注意:本题与主站 346 题相同: https://leetcode-cn.com/problems/moving-average-from-data-stream/
(这个是会员题...)
标签
设计, 队列, 数组, 数据流
题解
【滑动窗口的平均值】简单模拟
模拟
使用队列模拟即可,没有队列数据结构的也可以使用循环数组手动实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class MovingAverage:
def __init__(self, size: int): """ Initialize your data structure here. """ self.st = deque(maxlen=size) self.cnt = 0
def next(self, val: int) -> float: if len(self.st) == self.st.maxlen: self.cnt -= self.st.popleft() self.st.append(val) self.cnt += val return self.cnt / len(self.st)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class MovingAverage { Deque<Integer> st = new ArrayDeque<>(); int n, cnt; public MovingAverage(int size) { n = size; cnt = 0; } public double next(int val) { if (st.size() == n) cnt -= st.pollFirst(); cnt += val; st.addLast(val); return (double) cnt / st.size(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class MovingAverage { public: queue<int> st; int n, cnt; MovingAverage(int size): n(size), cnt(0) { } double next(int val) { if (st.size() == n) cnt -= st.front(), st.pop(); cnt += val; st.push(val); return (double) cnt / st.size(); } };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| typedef struct { int n, sum, cnt, top, tail; int* st; } MovingAverage;
MovingAverage* movingAverageCreate(int size) { MovingAverage* obj = (MovingAverage*) malloc(sizeof(MovingAverage)); obj->n = size; obj->sum = 0; obj-> cnt = 0; obj->top = 0; obj->tail = 0; obj->st = (int*) malloc(sizeof(int) * size); return obj; }
double movingAverageNext(MovingAverage* obj, int val) { if (obj->cnt > 0 && (obj->top + obj->n - obj->tail) % obj->n == 0) { obj->sum -= obj->st[obj->tail]; obj->tail = (obj->tail + 1) % obj->n; obj->cnt--; } obj->sum += val; obj->st[obj->top] = val; obj->top = (obj->top + 1) % obj->n; obj->cnt++; return (double) obj->sum / obj->cnt; }
void movingAverageFree(MovingAverage* obj) { free(obj->st); free(obj); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
var MovingAverage = function(size) { this.st = new Array(size).fill(0); this.n = size; this.sum = 0; this.cnt = 0; this.top = 0; this.tail = 0; };
MovingAverage.prototype.next = function(val) { if (this.cnt > 0 && (this.top + this.n - this.tail) % this.n == 0) { this.sum -= this.st[this.tail]; this.tail = (this.tail + 1) % this.n; this.cnt -= 1; } this.sum += val; this.st[this.top] = val; this.top = (this.top + 1) % this.n; this.cnt += 1; return this.sum / this.cnt; };
|
- 时间复杂度: 初始化及
next
操作均为 \(O(1)\)
- 空间复杂度: \(O(size)\)
如果对你有帮助的话,请给我点个赞吧~
欢迎前往 我的博客
或 Algorithm -
Github 查看更多题解