LeetCode「数据流中的移动平均值」代码输出异常求助
问题分析与修复:LeetCode「Moving Average from Data Stream」代码错误
核心问题:逻辑错误(索引处理混乱)
你的代码问题出在窗口填满后的索引管理逻辑,和数据转换无关,具体问题如下:
- rear变量的错误重置:当
rear达到数组长度(窗口填满)后,你用rear = (rear+1) % data.length -1计算新索引,这个逻辑完全错误。比如窗口大小为5,rear等于5时,计算后rear会变成0,后续调用next时,rear < data.length成立,错误进入初始填充分支,导致新元素被重复累加,而非替换窗口中最旧的元素。 - 索引含义混淆:你把
rear同时用作「已插入元素计数」和「数组索引」,两种用途冲突,导致窗口填满后的逻辑彻底混乱。
修复方案
方案一:数组实现循环队列(优化你的原始思路)
调整索引管理逻辑,用count记录当前窗口元素数量,front标记窗口起始位置,避免混乱:
class MovingAverage { private int size; private int[] data; private int count; private int front; private double sum; public MovingAverage(int size) { this.size = size; data = new int[size]; count = 0; front = 0; sum = 0.0; } public double next(int val) { if (count < size) { // 窗口未填满,直接添加到数组对应位置 data[count] = val; sum += val; count++; } else { // 窗口已满,移除最旧元素,添加新元素 sum -= data[front]; data[front] = val; sum += val; // 移动起始索引到下一个位置 front = (front + 1) % size; } return sum / count; } }
方案二:用Queue实现(更简洁直观)
利用队列「先进先出」的特性,完美匹配滑动窗口需求,代码更简洁:
import java.util.LinkedList; import java.util.Queue; class MovingAverage { private Queue<Integer> queue; private int size; private double sum; public MovingAverage(int size) { this.size = size; queue = new LinkedList<>(); sum = 0.0; } public double next(int val) { if (queue.size() == size) { // 移除队首的最旧元素,更新sum sum -= queue.poll(); } // 添加新元素到队尾 queue.add(val); sum += val; // 返回当前窗口的平均值 return sum / queue.size(); } }
验证你的测试用例
以你提供的调用序列为例:
- 前5次调用后,窗口填满,sum为
12009+1965-940-8516-16446 = -11928,返回-11928/5 = -2385.6 - 第6次调用传入7870,移除最旧的12009,sum变为
-11928 -12009 +7870 = -16067,返回-16067/5 = -3213.4 - 后续调用都会正确替换窗口中的最旧元素,计算平均值。
内容的提问来源于stack exchange,提问作者Ryan Ren
相关产品推荐
相关产品推荐

