Moving Average from Data Stream Using Queue
Calculate the moving average from a data stream using a queue with fixed window size. LeetCode 346 solution with O(1) per operation.
What you'll learn
- ✓How to maintain a running average with a fixed window
- ✓Queue as a sliding window data structure
- ✓O(1) time per operation using a running sum
- ✓Real-world applications in signal processing
Prerequisites
- •Queue basics — see Stacks & Queues Intro
Design a class that calculates the moving average of the last size values from a data stream.
Solution
from collections import deque
class MovingAverage:
def __init__(self, size):
self.size = size
self.queue = deque()
self.total = 0
def next(self, val):
"""
Add value and return current moving average.
Time: O(1), Space: O(size)
"""
self.queue.append(val)
self.total += val
if len(self.queue) > self.size:
self.total -= self.queue.popleft()
return self.total / len(self.queue)
Trace
MovingAverage(size=3)
next(1): queue=[1], total=1, avg=1/1 = 1.0
next(10): queue=[1,10], total=11, avg=11/2 = 5.5
next(3): queue=[1,10,3], total=14, avg=14/3 = 4.667
next(5): queue=[10,3,5], total=18, avg=18/3 = 6.0 ← 1 removed
Why Not Recalculate?
Summing all elements each time is O(size). By maintaining a running sum and subtracting the removed element, each operation is O(1).
Circular Buffer Alternative
class MovingAverageCircular:
def __init__(self, size):
self.size = size
self.buffer = [0] * size
self.total = 0
self.count = 0
self.idx = 0
def next(self, val):
self.total -= self.buffer[self.idx]
self.buffer[self.idx] = val
self.total += val
self.idx = (self.idx + 1) % self.size
self.count = min(self.count + 1, self.size)
return self.total / self.count
Edge Cases
- Window not full yet — divide by actual count, not size
- Single element window — each value is its own average
- Negative values — works correctly with running sum
- Very large values — consider overflow in languages without arbitrary precision
When to Use This Pattern
- Financial data (moving average of stock prices)
- Sensor smoothing (noise reduction)
- Network monitoring (average latency over window)
- Any streaming aggregation with fixed window
Related Problems
- Design Hit Counter (LeetCode 362)
- Number of Recent Calls (LeetCode 933)
- Sliding Window Median (LeetCode 480)
Related articles
- DSA Queues and Deques: FIFO, Double-Ended, and Circular
Master queue variants — simple queue, deque, circular queue, and priority queue. Implementations in Python with BFS, sliding window, and scheduling examples.
- DSA Deque Design Patterns — Sliding Window, Palindrome, Work Stealing
Master deque design patterns including sliding window maximum, palindrome checking, work stealing, and BFS/DFS hybrid. Python implementations.
- DSA BFS Pattern with Queues: Level-Order and Shortest Path
Master BFS using queues for tree level-order traversal and shortest path in unweighted graphs. Python implementations with detailed traces.
- DSA Design Circular Deque — Array-Based Implementation (LeetCode 641)
Design a Circular Deque with front/rear pointers on a fixed-size array. Python solution with all O(1) operations, visual trace, and edge case handling.