Skip to content
← All posts

Defuse the Bomb: Circular Sliding Window

5 min read
leetcodeproblemeasyarrayssliding-window

LeetCode Defuse the Bomb (Problem 1652) asks you to decrypt a circular code. You are given a circular array code of length n and an integer k. You need to replace every element simultaneously according to three rules:

  • If k > 0, replace code[i] with the sum of the next k elements (wrapping around).
  • If k < 0, replace code[i] with the sum of the previous |k| elements (wrapping around).
  • If k == 0, replace every element with 0.

The problem

You receive a bomb's circular code and a key. For each position in the array, you sum up a fixed number of neighbors in one direction and write that sum into the output. The array is circular, so when you go past the end, you wrap back to the beginning, and when you go before the start, you wrap to the end.

For example, with code = [5, 7, 1, 4] and k = 3, the output is [12, 10, 16, 13]. Each element gets replaced by the sum of the next 3 elements, wrapping around the circular array.

5i=07i=11i=24i=3k = 3
The array is circular. For i=0 (blue) with k=3, sum the next 3 elements (green dashed): 7 + 1 + 4 = 12.

The brute force approach

The direct approach is to loop through every index i, then for each one, sum the next k elements using modular arithmetic to handle the wrap-around. That gives you n outer iterations, each doing k additions, for a total of O(n * k) time.

This works, but it repeats a lot of work. When you move from i to i + 1, the window of k elements you are summing shifts by just one position. You drop one element from the left side of the window and add one element on the right. The other k - 1 elements are the same. A sliding window exploits this overlap.

The key insight

Because the array is circular, you can think of the window as a fixed-size segment that slides around a ring. When you advance to the next index, you subtract the element that just left the window and add the element that just entered. Each slide is O(1), and you make n slides total, giving O(n) time.

The modular index % n handles the circular wrap-around. You never need to duplicate the array or build a second copy. Just compute indices modulo n as you slide.

The circular sliding window is just a regular sliding window where every index is computed % n. The window size stays fixed at |k|, and you slide it once per output element.

Step-by-step walkthrough

Let's trace through code = [5, 7, 1, 4] with k = 3. For each position, we sum the next 3 elements (circularly). The blue cell is the current index, and green cells are the window being summed.

Step 0: Initial window. Sum code[1..3] for result[0].

code50711243result12???

Window sum = 7 + 1 + 4 = 12. result[0] = 12.

Step 1: Slide window. Drop code[1], add code[0] (wraps). Sum for result[1].

code50711243result1210??

Window sum = 12 - 7 + 5 = 10. result[1] = 10.

Step 2: Slide window. Drop code[2], add code[1] (wraps). Sum for result[2].

code50711243result121016?

Window sum = 10 - 1 + 7 = 16. result[2] = 16.

Step 3: Slide window. Drop code[3], add code[2] (wraps). Sum for result[3].

code50711243result12101613

Window sum = 16 - 4 + 1 = 13. result[3] = 13.

Notice how each step drops one element from the window and adds one new element. The window sum updates in O(1), and after n slides, you have the full result: [12, 10, 16, 13].

The code

def decrypt(code: list[int], k: int) -> list[int]:
    n = len(code)
    result = [0] * n

    if k == 0:
        return result

    start = 1 if k > 0 else n + k
    end = k if k > 0 else n - 1
    window_sum = sum(code[start:end + 1])

    for i in range(n):
        result[i] = window_sum
        window_sum -= code[start % n]
        window_sum += code[(end + 1) % n]
        start += 1
        end += 1

    return result

The function starts by handling the k == 0 case, returning all zeros. For k > 0, the initial window covers indices 1 through k. For k < 0, the initial window covers the |k| elements before index 0, which are indices n + k through n - 1.

After computing the first window sum, the loop slides the window forward one position per iteration. It records the current sum, subtracts the element leaving the window, and adds the element entering. The modular arithmetic (% n) ensures everything wraps correctly around the circular array.

The start and end pointers grow beyond n, but the % n in the subtract and add lines keeps the actual array access in bounds. You do not need to reset start or end back to zero.

Complexity analysis

ApproachTimeSpace
Brute forceO(n * k)O(n)
Sliding windowO(n)O(n)

Time: The sliding window approach computes the initial window sum in O(k), then performs n constant-time slides. Since k is at most n, the total is O(n). The brute force approach does O(k) work per index, totaling O(n * k).

Space: Both approaches allocate an output array of size n, so space is O(n). The sliding window uses only a few extra variables beyond that.

The building blocks

1. Modular indexing for circular arrays

The core technique for circular array problems is computing index % n to wrap around the boundaries:

next_index = (i + offset) % n
prev_index = (i - offset + n) % n

This same trick appears in Rotate Array, Circular Queue implementations, and any problem where the array logically connects end to start. Once you internalize % n, circular arrays stop feeling like a special case and become just another index calculation.

2. Fixed-size sliding window

The window has a constant width of |k|. On each slide, you subtract the outgoing element and add the incoming element. This "subtract one, add one" pattern is the foundation of every fixed-size sliding window:

window_sum -= code[left]
window_sum += code[right + 1]
left += 1
right += 1

You will see this exact pattern in Maximum Average Subarray, Grumpy Bookstore Owner, and any problem that asks for a running sum or count over a window of fixed length.

Edge cases

  • k equals zero: Every element becomes 0. Return a zero-filled array immediately.
  • k equals n minus 1: The window covers every element except the current one. Each result entry is the total array sum minus code[i].
  • k is negative: The window looks backward instead of forward. The same sliding window logic works; you just initialize the window behind the current index.
  • All elements are the same: Every output value is code[0] * |k|. A good sanity check for your implementation.

From understanding to recall

The circular sliding window pattern combines two ideas: modular indexing and the fixed-size window. Separately, each is simple. Together, they require you to get the initial window bounds right, slide in the correct direction, and handle the % n at every access. These are the details that slip under pressure.

Spaced repetition helps you lock in the setup. After a few rounds of writing the initialization (choosing start and end based on the sign of k) and the slide loop from memory, the pattern becomes automatic. You see "circular" and "fixed window" in a problem description, and the template is already in your fingers.

Related posts