Why I Stopped Thinking About Arrays And Started Thinking About Windows
There’s this specific 3 second window after you hit submit on LeetCode.
Why I Stopped Thinking About Arrays And Started Thinking About Windows

Sliding Window Witty Illustration.
There’s this specific 3 second window after you hit submit on LeetCode.
Your solution is running. You’re 70% confident. You’re already mentally moving to the next problem. Life is good.
Then — Time Limit Exceeded.
Two loops. O(n²). Array size 10⁷. It was never going to work. Some part of you knew. You submitted anyway. That part of you has terrible judgment and we need to talk about it.
This is the pattern that finally got me out of that loop (pun intended, no apologies.) It quietly fixed how I think about array problems, and it came with three very specific mistakes I had to make first. The mistakes are more useful than the solution. Nobody writes about those. I will. (genuine ones, not made up for content.)
And if you stick around till the end — there’s a curated set of problems, sequenced deliberately, that will tell you exactly how well you understood this. Not random LeetCode grinding — five problems in the right order.
What’s inside:
- What even is a window
- Fixed vs variable window— how to tell
- The actual intuition behind it
- The mistakes I actually made
- Now prove it to yourself
Okay but what even is a “window”
Not the Wikipedia definition. A real one.
A window is just the chunk of the array you’re currently paying attention to. Not the whole thing — a piece of it. Contiguous, connected, no gaps in between. Think of an actual window in your room. You don’t see the entire street. You see a section of it. Could be wide, could be narrow, you can shift it — but you can’t skip the wall and peek at the house two blocks down.
Sliding just means that chunk moves. Based on what you find — sum too high, constraint broken, target hit — you expand it, shrink it, or push it forward.
Here’s what that actually looks like on an array:

Image illustration for sliding window
The window shifted. You dropped the 1 on the left, picked up the 1 on the right. That’s it. That’s sliding.
That’s genuinely the whole idea. Everything else is just rules for when and how to move. Anyone who made it sound more complicated than this was either confused themselves or just really liked the sound of their own explanation.
Fixed or variable — your problem is already telling you, you just have to listen
There are two types and the problem description picks for you. The catch is you have to actually read it. (Revolutionary concept, I know.)
Fixed size — the problem hands you the window length directly. “Find the maximum sum subarray of length k.” The window never changes shape. You drag it across the array, drop whatever’s leaving from the left, pick up whatever’s entering from the right, track your result. Mechanical. Clean. Almost satisfying.
Say array is [2, 1, 5, 1, 3] and k = 3. You're looking for max sum subarray of length 3.
Window 1: [2, 1, 5] → sum = 8
Window 2: [1, 5, 1] → sum = 7
Window 3: [5, 1, 3] → sum = 9 ← answer
No recalculation. You just subtract what left and add what entered.
sum = sum - arr[left] + arr[right]
One line. O(n). Done.
Variable size — the problem gives you a condition instead of a size. “Find the number of subarrays whose sum is ≤ k — all elements positive.” Now the window breathes. It grows when things are good, shrinks when they’re not.
The tell is always in the constraint. A fixed k describing a length → fixed window. A condition like ≤ k on the result → variable window.
Read the constraint before anything else. Before the examples, before the hints, and definitely before you open the discussion tab and accidentally see the solution title. (Hate this. We’ve all done it. It doesn’t feel great.)
The intuition behind it — because “it’s faster” isn’t a good enough answer
Same variable window problem. Find subarrays with sum ≤ k, all positive elements.
Brute force says: start at index 0, run to the end, check everything. Then start at index 1, run to the end again. Repeat until done. Total subarrays in an array of size n is n(n+1)/2. That's O(n²). For n = 10⁷ that is approximately "your laptop fans turn on and absolutely nothing gets submitted."
Here’s what sliding window notices that brute force is too busy looping to see.
Take array [1, 2, 1, 3], k = 3.
You’re at index 0, summing forward:
[1] → sum = 1 ✓
[1, 2] → sum = 3 ✓
[1, 2, 1] → sum = 4 ✗ crossed k. Stop.
You’re done with index 0. With all positive numbers, adding more can only make it worse.
Brute force now starts fresh at index 1:
[2] → sum = 2 ✓
[2, 1] → sum = 3 ✓
[2, 1, 3] → sum = 6 ✗
But wait — when you were at index 0 and summing forward, you already computed [2] and [2, 1]. You had that information. And you threw it in the bin.
Sliding window doesn’t throw it away. When the sum crosses k, it removes the leftmost element and adjusts:
[1, 2, 1] → sum = 4 ✗ → remove 1 from left
[2, 1] → sum = 3 ✓ → continue from here
No restart. No recalculation. The window just shrinks and keeps moving.
Every element enters the window once. Every element leaves once. That’s O(n).
The core logic in code looks like this:
int start = 0, sum = 0;
for (int end = 0; end < arr.length; end++) {
sum += arr[end]; // expand right
while (sum > k) {
sum -= arr[start]; // shrink left
start++;
}
// window is valid here — do your thing
}
The “sliding” isn’t some clever trick someone invented. It’s just the natural result of refusing to recalculate things you already know. Which, in hindsight, feels obvious. Most good ideas do.
The mistakes I made. The real ones.
1. Positive vibes only. Except the input wasn’t — I forgot negative numbers exist
Subarray problem. Reached for sliding window immediately. Classic. The input had negative numbers. I didn’t check. Spent a solid twenty minutes debugging code that was logically correct for a problem sliding window genuinely cannot solve.
Here’s the guarantee sliding window depends on: with all positive numbers, expanding the window always increases the sum, shrinking it always decreases it. The window always knows which way to push.
Negative numbers blow that up completely.
Array: [3, -2, 5], k = 4
Window [3] → sum = 3 ✓
Window [3, -2] → sum = 1 ✓ (expanded but sum went DOWN)
Window [3,-2,5] → sum = 6 ✗
Remove 3 →
Window [-2, 5] → sum = 3 ✓ (shrunk but sum went UP)
The window has no idea which direction actually helps. It’s just guessing. If you see negative integers in a subarray sum problem — that’s prefix sum with a hashmap, not sliding window. The positive-only constraint isn’t small print. It’s the whole foundation.
2. I debugged perfect code for 30 minutes. The code was never the problem — I misread ≤ k as = k
Problem said ≤ k. I solved = k. Passed 40 test cases, failed the 41st, spent thirty minutes debugging code that had zero bugs — because I was solving a slightly different problem that lived only in my head.
Problem: count subarrays with sum ≤ k
My code: count subarrays with sum == k
For array [1, 1, 1], k = 2:
Correct answer: 5 ([1], [1], [1], [1,1], [1,1])
My answer: 2 ([1,1], [1,1])
Three characters. 30 minutes. Read the constraint twice. Every time.
3. The stale element incident
Advanced sliding window, I got a little too clever and jumped the left pointer directly to a new position — skipping several elements at once. Smart optimization. Except I forgot to remove those skipped elements from my tracking structure.
Window before jump: [a, b, c, d]
↑
start
I jumped start directly to d:
Window after jump: [a, b, c, d]
↑
start
My tracking structure still thought a, b, c were in the window.
They weren't. They'd been evicted but never actually removed.
The window moved. The data didn’t get the memo. Everything downstream was reading elements that hadn’t been part of the current window for several steps — completely confidently, completely wrong.
The rule I follow now: whenever the left pointer moves, before anything else — did everything that left the window actually leave? If I have to pause and think about it, the answer is no.
Now prove it to yourself — in this order
Don’t randomise this. The sequence is the point.
1. Maximum Average Subarray I — LeetCode 643 Fixed window. Start here, no arguments.
2. Longest Substring Without Repeating Characters — LeetCode 3 Your first variable window. Classic for a reason.
3. Fruit Into Baskets — LeetCode 904 Variable window with something extra to track. You’ll know what I mean when you see it.
4. Number of Subarrays with Product Less Than K — LeetCode 713 Same energy as the example in this article. Different twist.
5. Minimum Window Substring — LeetCode 76 Hard level. Do not skip to this one.
Solve them in order. If you get stuck, the answer is somewhere in this article — not in the discussion tab.
What this actually taught me
The first time sliding window clicked, I thought I’d just learned a faster way to handle subarray problems.
I hadn’t. I’d learned something that shows up everywhere once you see it: stop recalculating things you already know.
That’s the real pattern. Not two pointers. Not shrink-left-expand-right. The actual lesson is recognizing when you’re doing redundant work — and refusing to do it. In your algorithm and honestly in how you approach problems in general.
That instinct has been more useful than any template I’ve memorized. The window slides. But so does your thinking — once you stop throwing away what you already figured out.
I write about DSA, backend engineering, and the genuinely unsexy process of getting good at this. No polished highlights — just the real process. Follow if that sounds like your kind of read.
메타데이터
- post_id
- e776edf99dd1
- slug
- why-i-stopped-thinking-about-arrays-and-started-thinking-about-windows-e776edf99dd1
- url
- https://blog.devgenius.io/why-i-stopped-thinking-about-arrays-and-started-thinking-about-windows-e776edf99dd1
- canonical_url
- https://blog.devgenius.io/why-i-stopped-thinking-about-arrays-and-started-thinking-about-windows-e776edf99dd1
- author_url
- https://medium.com/@darshanpadia5
- status
- ok
- fetched_at
- 2026-06-12 07:40:50