Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1652. Defuse the Bomb - Leetcode Solution

Problem Description

You are given a code array of integers of length n and an integer k. The task is to create a new array answer of length n such that:

  • If k > 0, for each index i, answer[i] is the sum of the next k elements of code (wrapping around the array as needed).
  • If k < 0, for each index i, answer[i] is the sum of the previous |k| elements of code (wrapping around as needed).
  • If k == 0, for each index i, answer[i] = 0.

The array is considered circular, so when summing beyond the end or before the start, you wrap around to the other side.

Constraints:

  • n == code.length
  • 1 <= n <= 100
  • 1 <= code[i] <= 100
  • -(n-1) <= k <= n-1

Thought Process

At first glance, the problem seems to require, for each position, summing either the next k or previous |k| numbers, considering the array wraps around. The brute-force approach would be to loop for each index and sum the required elements directly, handling the wrap-around using modulo arithmetic.

However, this would result in nested loops, leading to a time complexity of O(n * |k|), which is acceptable for small arrays but not optimal. To optimize, we can leverage the sliding window technique, since for each index, the set of elements to sum is just shifted by one from the previous index. This way, we avoid recomputing the sum from scratch each time.

The main challenge is handling the circular nature of the array efficiently, ensuring that indices wrap around properly whether moving forward or backward.

Solution Approach

Let's break down the steps to solve the problem efficiently:

  • Handle the k == 0 case: If k is zero, every element in the answer is zero. We can return an array of zeros immediately.
  • Sliding Window for k > 0:
    • For each index i, sum the next k elements: code[(i+1) % n] through code[(i+k) % n].
    • We can use a window sum: start by summing the first k elements after index 0, then for each subsequent index, subtract the element leaving the window and add the new element entering the window, using modulo to wrap around.
  • Sliding Window for k < 0:
    • For each index i, sum the previous |k| elements: code[(i-1+n)%n] through code[(i+|k|-n)%n].
    • Similarly, use a sliding window in the reverse direction, adjusting indices with modulo to wrap around.
  • Why Sliding Window: This technique reduces redundant computation. Instead of summing up to k elements for every index, we do the sum once and adjust by updating just two elements as we move the window.
  • Implementation Details:
    • Use modulo arithmetic to handle wrapping.
    • Initialize the window sum, then update it as you iterate through the array.

Example Walkthrough

Let's use code = [5, 7, 1, 4] and k = 3.

  • Since k > 0, for each index, sum the next 3 elements (circularly).
    • For index 0: sum of code[1] + code[2] + code[3] = 7 + 1 + 4 = 12
    • For index 1: sum of code[2] + code[3] + code[0] = 1 + 4 + 5 = 10
    • For index 2: sum of code[3] + code[0] + code[1] = 4 + 5 + 7 = 16
    • For index 3: sum of code[0] + code[1] + code[2] = 5 + 7 + 1 = 13
  • The answer array is [12, 10, 16, 13].
  • With k = -2:
    • For index 0: sum of previous 2: code[3] + code[2] = 4 + 1 = 5
    • For index 1: code[0] + code[3] = 5 + 4 = 9
    • For index 2: code[1] + code[0] = 7 + 5 = 12
    • For index 3: code[2] + code[1] = 1 + 7 = 8
    The answer is [5, 9, 12, 8].

Time and Space Complexity

  • Brute-force: For each index, sum up to |k| elements, leading to O(n * |k|) time complexity. Space is O(n) for the answer array.
  • Optimized (Sliding Window): We compute the initial window sum in O(|k|), and then for each of the n elements, we update the sum in O(1), for a total of O(n + |k|) time. Space is O(n) for the result.
  • Since n is small, both approaches are feasible, but sliding window is more efficient and scales better for larger inputs.

Summary

The "Defuse the Bomb" problem is an excellent exercise in circular array manipulation and demonstrates the value of the sliding window technique for reducing redundant calculations. By carefully handling wrap-around indices and updating window sums efficiently, we achieve an elegant and optimal solution. The key insight is that for each position, the set of elements to sum only changes by one, making sliding window a natural fit.

Code Implementation

class Solution:
    def decrypt(self, code, k):
        n = len(code)
        if k == 0:
            return [0] * n
        answer = [0] * n
        for i in range(n):
            s = 0
            if k > 0:
                for j in range(1, k+1):
                    s += code[(i + j) % n]
            else:
                for j in range(1, -k+1):
                    s += code[(i - j + n) % n]
            answer[i] = s
        return answer
      
class Solution {
public:
    vector<int> decrypt(vector<int>& code, int k) {
        int n = code.size();
        vector<int> answer(n, 0);
        if (k == 0) return answer;
        for (int i = 0; i < n; ++i) {
            int s = 0;
            if (k > 0) {
                for (int j = 1; j <= k; ++j) {
                    s += code[(i + j) % n];
                }
            } else {
                for (int j = 1; j <= -k; ++j) {
                    s += code[(i - j + n) % n];
                }
            }
            answer[i] = s;
        }
        return answer;
    }
};
      
class Solution {
    public int[] decrypt(int[] code, int k) {
        int n = code.length;
        int[] answer = new int[n];
        if (k == 0) return answer;
        for (int i = 0; i < n; ++i) {
            int s = 0;
            if (k > 0) {
                for (int j = 1; j <= k; ++j) {
                    s += code[(i + j) % n];
                }
            } else {
                for (int j = 1; j <= -k; ++j) {
                    s += code[(i - j + n) % n];
                }
            }
            answer[i] = s;
        }
        return answer;
    }
}
      
var decrypt = function(code, k) {
    const n = code.length;
    if (k === 0) return Array(n).fill(0);
    const answer = new Array(n).fill(0);
    for (let i = 0; i < n; ++i) {
        let s = 0;
        if (k > 0) {
            for (let j = 1; j <= k; ++j) {
                s += code[(i + j) % n];
            }
        } else {
            for (let j = 1; j <= -k; ++j) {
                s += code[(i - j + n) % n];
            }
        }
        answer[i] = s;
    }
    return answer;
};