持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第27天,点击查看活动详情
剑指 Offer II 041. 滑动窗口的平均值:
给定一个整数数据流和一个窗口大小,根据该滑动窗口的大小,计算滑动窗口里所有数字的平均值。
实现 MovingAverage 类:
MovingAverage(int size)用窗口大小size初始化对象。double next(int val)成员函数next每次调用的时候都会往滑动窗口增加一个整数,请计算并返回数据流中最后size个值的移动平均值,即滑动窗口里所有数字的平均值。
样例 1:
输入:
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
- -105 <= val <= 105
- 最多调用 next 方法 104 次
分析
- 面对这道算法题目,二当家的陷入了沉思。
- 计算平均值仅需要总值和数量,但是当数字的数量超过滑动窗口的大小时,就需要将前面的数字移除,先进先出,用队列实现最直观。
题解
rust
struct MovingAverage {
size: usize,
sum: i32,
q: std::collections::VecDeque<i32>,
}
/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl MovingAverage {
/** Initialize your data structure here. */
fn new(size: i32) -> Self {
MovingAverage{
size: size as usize,
sum: 0,
q: std::collections::VecDeque::new()
}
}
fn next(&mut self, val: i32) -> f64 {
if self.q.len() == self.size {
self.sum -= self.q.pop_front().unwrap();
}
self.q.push_back(val);
self.sum += val;
self.sum as f64 / self.q.len() as f64
}
}
/**
* Your MovingAverage object will be instantiated and called as such:
* let obj = MovingAverage::new(size);
* let ret_1: f64 = obj.next(val);
*/
go
type MovingAverage struct {
size int
sum int
q []int
}
/** Initialize your data structure here. */
func Constructor(size int) MovingAverage {
return MovingAverage{size: size}
}
func (this *MovingAverage) Next(val int) float64 {
if len(this.q) == this.size {
this.sum -= this.q[0]
this.q = this.q[1:]
}
this.sum += val
this.q = append(this.q, val)
return float64(this.sum) / float64(len(this.q))
}
/**
* Your MovingAverage object will be instantiated and called as such:
* obj := Constructor(size);
* param_1 := obj.Next(val);
*/
c++
class MovingAverage {
private:
int size;
int sum;
queue<int> q;
public:
/** Initialize your data structure here. */
MovingAverage(int size) {
this->sum = 0;
this->size = size;
}
double next(int val) {
if (this->q.size() == this->size) {
this->sum -= this->q.front();
this->q.pop();
}
this->sum += val;
this->q.emplace(val);
return this->sum * 1.0 / this->q.size();
}
};
/**
* Your MovingAverage object will be instantiated and called as such:
* MovingAverage* obj = new MovingAverage(size);
* double param_1 = obj->next(val);
*/
java
class MovingAverage {
private final int size;
private int sum;
private final Queue<Integer> q = new LinkedList<>();
/** Initialize your data structure here. */
public MovingAverage(int size) {
this.size = size;
}
public double next(int val) {
if (q.size() == size) {
sum -= q.poll();
}
sum += val;
q.offer(val);
return sum * 1.0 / q.size();
}
}
/**
* Your MovingAverage object will be instantiated and called as such:
* MovingAverage obj = new MovingAverage(size);
* double param_1 = obj.next(val);
*/
python
class MovingAverage:
def __init__(self, size: int):
"""
Initialize your data structure here.
"""
self.size = size
self.sum = 0
self.q = deque()
def next(self, val: int) -> float:
if len(self.q) == self.size:
self.sum -= self.q.popleft()
self.sum += val
self.q.append(val)
return self.sum / len(self.q)
# Your MovingAverage object will be instantiated and called as such:
# obj = MovingAverage(size)
# param_1 = obj.next(val)
原题传送门:https://leetcode.cn/problems/qIsx9U/
非常感谢你阅读本文~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://juejin.cn/user/2771185768884824/posts 博客原创~