【算法】剑指 Offer II 041. 滑动窗口的平均值(多语言实现)

128 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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 博客原创~