โ† Back to list

๐Ÿง  Why Sliding Window Felt So Simple After Solving Graph Problems

By Sai Pranav Moluguri

Sai Pranav Moluguri ยท 2026-07-10 15:23 ยท 0 claps ยท 5.4 min read
#sliding-windows #algorithms #problem-solving #leetcode #software-engineering
Open on Medium โ†—
Wiki topics: ๐Ÿ’ป ยท Programming ๐Ÿ”ง ยท Data Engineering

๐Ÿง  Why Sliding Window Felt So Simple After Solving Graph Problems

By Sai Pranav Moluguri

Recently, I revisited the Sliding Window pattern after spending a lot of time solving graph problems.

I had been working with:

  • BFS and DFS
  • Grid directions
  • Boundary conditions
  • Visited sets
  • Queues and stacks
  • Multi-Source BFS
  • State-Based BFS

Compared to all of that, Sliding Window suddenly felt surprisingly simple.

At first, I wondered whether I was missing something.

But then I realized that the core movement really is just two steps:

1. Expand the window using the end pointer.
2. Shrink the window using the start pointer when the condition breaks.

That was the moment Sliding Window finally clicked for me.

The Basic Idea

A window represents a contiguous section of an array.

We use two pointers:

start
end

The end pointer expands the window by adding new elements.

The start pointer shrinks the window by removing old elements.

The general structure looks like this:

start = 0
for end in range(len(nums)):
    # Add nums[end] to the window
    while window_is_invalid:
        # Remove nums[start] from the window
        start += 1
    # Process the valid window

After solving complex graph problems, this felt refreshingly clean.

There was no visited set.

No four-directional movement.

No queue containing nodes and distances.

No need to prevent cycles.

Just expand, shrink and process.

Fixed-Size Sliding Window

The first version is the fixed-size window.

Here, the size of the window is already given.

For example, if the window size is k, we keep exactly k elements inside the window.

The pattern is:

1. Add the new element.
2. Remove the element leaving the window.
3. Process the current window.

The window moves across the array without changing its size.

[1, 2, 3], 4, 5
     โ†“
1, [2, 3, 4], 5
        โ†“
1, 2, [3, 4, 5]

Once I understood this movement, fixed-size Sliding Window became very mechanical.

Variable-Size Sliding Window

The second version is the variable-size window.

Here, the size is not fixed.

We continue expanding the window until a condition breaks. When it breaks, we shrink the window until it becomes valid again.

The pattern is:

1. Expand using end.
2. While the condition is invalid, shrink using start.
3. Record the answer.

For example, I wrote this function to find a subarray whose sum equals a target:

def find_subarray_sum(nums, target_sum):
    start = 0
    current_sum = 0
    for end in range(len(nums)):
        current_sum += nums[end]
        while current_sum > target_sum:
            current_sum -= nums[start]
            start += 1
        if current_sum == target_sum:
            return (start, end)
    return None

Every time end moves, a new element enters the window:

current_sum += nums[end]

If the sum becomes too large, elements leave from the beginning:

while current_sum > target_sum:
    current_sum -= nums[start]
    start += 1

That is the entire movement.

Expand โ†’ Shrink when necessary โ†’ Check the answer

After working through graph traversals, I looked at this and thought:

Is that really all?

Mechanically, yes.

But I soon learned that the real difficulty is not writing the Sliding Window code.

It is recognizing when Sliding Window can actually be used.

The Problem That Exposed the Limitation

I tried solving LeetCode 560:

Subarray Sum Equals K

The problem asks us to return the total number of contiguous subarrays whose sum equals k.

At first glance, it looked like a perfect variable-size Sliding Window problem.

I wrote:

class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        start = 0
        count = 0
        current_sum = 0
        for end in range(len(nums)):
            current_sum += nums[end]
            while current_sum > k:
                current_sum -= nums[start]
                start += 1
            if current_sum == k:
                count += 1
        return count

The solution passed some test cases, but then it failed.

One of the failing inputs was:

nums = [-1, -1, 1]
k = 0

The expected answer was:

1

Because this subarray has a sum of zero:

[-1, 1]

But my code returned zero.

That failure taught me the most important Sliding Window lesson.

Why Negative Numbers Break the Pattern

Sliding Window works when expanding and shrinking affect the condition predictably.

With positive numbers:

  • Adding an element increases the sum.
  • Removing an element decreases the sum.

Therefore, if the sum becomes too large, moving start forward makes sense.

But negative numbers break this predictable movement.

For example:

  • Adding -5 decreases the sum.
  • Removing -5 increases the sum.

So this logic is no longer reliable:

while current_sum > k:
    current_sum -= nums[start]
    start += 1

A sum greater than k might become equal to k after adding a negative number.

A sum less than k might become even smaller after expanding.

The window no longer knows which direction will bring it closer to the target.

That was when I understood that seeing the words โ€œcontiguous subarrayโ€ is not enough to immediately choose Sliding Window.

I also need to inspect the constraints.

LeetCode 560 clearly says:

-1000 <= nums[i] <= 1000

The array can contain negative numbers.

That single constraint changes the required pattern from Sliding Window to Prefix Sum with a frequency map.

The Real Pattern Recognition

My new decision process became:

Contiguous subarray problem
          โ†“
Can expanding and shrinking change the condition predictably?
          โ†“
Are negative numbers present?

If all values are positive or non-negative, Sliding Window may work.

If negative values are allowed in a sum-based problem, I need to be careful. Prefix Sum is often the appropriate pattern.

This was a valuable realization because it showed me that understanding an algorithm involves two different skills:

1. Knowing how the pattern works.
2. Knowing when the pattern works.

The implementation of Sliding Window is simple.

Recognizing its limitations is the deeper part.

Why Graphs Made Sliding Window Feel Easier

When solving a grid graph problem, I usually have to think about several things:

directions = [
    (0, 1),
    (0, -1),
    (1, 0),
    (-1, 0)
]

For every neighbor, I need to check:

  • Is the row valid?
  • Is the column valid?
  • Is the cell already visited?
  • Can I move into that cell?
  • Should I use BFS or DFS?
  • What information belongs in the state?
  • Am I calculating distance by levels?

In State-Based BFS, even reaching the same node may represent different situations.

For example:

(node, previous_edge_color)

But in Sliding Window, there are only two boundaries:

start
end

The end pointer explores new elements.

The start pointer removes elements that no longer belong.

That is why learning Sliding Window after graphs felt so different.

Graphs trained me to manage several moving parts at once. Sliding Window reduced everything to maintaining one contiguous range.

My Biggest Realization

The biggest realization was not simply:

Sliding Window is easy.

It was:

Once the correct pattern is identified, the implementation can become surprisingly simple.

For variable-size Sliding Window:

Expand the window.
Shrink it while invalid.
Process the valid window.

For fixed-size Sliding Window:

Add the incoming element.
Remove the outgoing element.
Process the window.

But before applying either pattern, I must ask:

Does moving the window change the condition predictably?

That question prevents me from forcing Sliding Window onto problems like Subarray Sum Equals K.

My Takeaway

Learning Sliding Window after graph problems made me appreciate how different algorithmic patterns manage information.

Graphs explore many possible paths.

Sliding Window maintains one continuous range.

Graphs often need a visited set to avoid repeating states.

Sliding Window moves each pointer forward, so every element enters and leaves the window at most once.

The code is small, but the recognition behind it still matters.

My final mental model is:

Fixed-size window:
Add โ†’ Remove โ†’ Process
Variable-size window:
Expand โ†’ Shrink while invalid โ†’ Process

And for sum-based problems:

Negative numbers present?
Do not automatically assume Sliding Window.

Sometimes, solving harder problems first makes another pattern suddenly look simple.

After working through grid graphs and State-Based BFS, Sliding Window gave me exactly that feeling.

It made me say:

Wowโ€ฆ is that really all?

And this time, the answer was:

Yes โ€” but only after identifying when it is valid.

About Me

I am Sai Pranav Moluguri, a recent Masterโ€™s graduate in Computer Science from Florida Atlantic University (FAU).

My interests include:

  • Backend Development
  • Full-Stack Engineering using the MERN Stack
  • Distributed Systems and Scalable Architectures
  • Artificial Intelligence and LLM Applications
  • Data Structures and Algorithms

I am currently preparing for Software Development Engineer opportunities while working toward my long-term goal of becoming a FAANG Software Engineer.

Forever Learning. Forever Growing.

โ€” Sai Pranav Moluguri


๋ฉ”ํƒ€๋ฐ์ดํ„ฐ
post_id
4c12fbea89bb
slug
why-sliding-window-felt-so-simple-after-solving-graph-problems-4c12fbea89bb
url
https://medium.com/@saipranavmoluguri2001/why-sliding-window-felt-so-simple-after-solving-graph-problems-4c12fbea89bb
canonical_url
https://medium.com/@saipranavmoluguri2001/why-sliding-window-felt-so-simple-after-solving-graph-problems-4c12fbea89bb
author_url
https://medium.com/@saipranavmoluguri2001
status
ok
fetched_at
2026-07-20 05:02:33