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:
k > 0
, for each index i
, answer[i]
is the sum of the next k
elements of code
(wrapping around the array as needed).k < 0
, for each index i
, answer[i]
is the sum of the previous |k|
elements of code
(wrapping around as needed).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
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.
Let's break down the steps to solve the problem efficiently:
k == 0
case: If k
is zero, every element in the answer is zero. We can return an array of zeros immediately.
k > 0
:
i
, sum the next k
elements: code[(i+1) % n]
through code[(i+k) % n]
.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.k < 0
:
i
, sum the previous |k|
elements: code[(i-1+n)%n]
through code[(i+|k|-n)%n]
.k
elements for every index, we do the sum once and adjust by updating just two elements as we move the window.
Let's use code = [5, 7, 1, 4]
and k = 3
.
k > 0
, for each index, sum the next 3 elements (circularly).
code[1]
+ code[2]
+ code[3]
= 7 + 1 + 4 = 12code[2]
+ code[3]
+ code[0]
= 1 + 4 + 5 = 10code[3]
+ code[0]
+ code[1]
= 4 + 5 + 7 = 16code[0]
+ code[1]
+ code[2]
= 5 + 7 + 1 = 13[12, 10, 16, 13]
.
k = -2
:
code[3]
+ code[2]
= 4 + 1 = 5code[0]
+ code[3]
= 5 + 4 = 9code[1]
+ code[0]
= 7 + 5 = 12code[2]
+ code[1]
= 1 + 7 = 8[5, 9, 12, 8]
.
|k|
elements, leading to O(n * |k|) time complexity. Space is O(n) for the answer array.
n
is small, both approaches are feasible, but sliding window is more efficient and scales better for larger inputs.
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.
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;
};