What did you learn? Queues naturally maintain a "sliding window" of elements. New elements enter at the back, old ones leave from the front.
Amortized analysis: even though the while loop can run multiple times per call, each element is enqueued and dequeued exactly once across all calls.
This pattern appears whenever you need to track "recent" items within some constraint. But queues have a limitation: you can only access the front. What if you need both ends?