Problem
You and a gang of thieves are planning on robbing a bank. You are given a 0-indexed integer array security
, where security[i]
is the number of guards on duty on the ith
day. The days are numbered starting from 0
. You are also given an integer time
.
The ith
day is a good day to rob the bank if:
- There are at least
time
days before and after theith
day, - The number of guards at the bank for the
time
days beforei
are non-increasing , and - The number of guards at the bank for the
time
days afteri
are non-decreasing.
More formally, this means day i
is a good day to rob the bank if and only if security[i - time] >= security[i - time + 1] >= ... >= security[i] <= ... <= security[i + time - 1] <= security[i + time]
.
Return a list ofall days (0-indexed) that are good days to rob the bank.The order that the days are returned in does****not matter.
Examples
Example 1
|
|
Example 2
|
|
Example 3
|
|
Constraints
1 <= security.length <= 10^5
0 <= security[i], time <= 10^5
Solution
Method 1 - Naive
A brute-force solution would check every potential day i
and then, for each one, loop time
days backward and time
days forward. This is inefficient because the checks for adjacent days (e.g., i
and i+1
) overlap significantly.
Method 1 - Prefix Sum
A better approach is to precompute the necessary information. We can determine if a day i
is a good day by answering two questions:
- How many consecutive days ending at
i
have non-increasing guards? - How many consecutive days starting at
i
have non-decreasing guards?
We can answer these questions for all days in linear time using two auxiliary arrays:
-
pre
array:pre[i]
will store the number of consecutive days ending ati
(inclusive) that satisfy the non-increasing condition. We can compute this with a single pass from left to right.pre[i] = pre[i-1] + 1
ifsec[i-1] >= sec[i]
.- Otherwise, the streak is broken, so
pre[i]
is reset to0
.
-
suf
array:suf[i]
will store the number of consecutive days starting ati
(inclusive) that satisfy the non-decreasing condition. We compute this with a single pass from right to left.suf[i] = suf[i+1] + 1
ifsec[i] <= sec[i+1]
.- Otherwise, the streak is broken, so
suf[i]
is reset to0
.
After populating pre
and suf
, we can make a final pass. A day i
is a “good day” if it has at least time
days before and after it, and both conditions are met. This translates to checking if pre[i] >= time
and suf[i] >= time
for all i
in the valid range [time, n - time)
.
Code
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n)
. We make three separate passes through the array: one to computepre
, one forsuf
, and one to find the answer. Each pass takesO(n)
time. - 🧺 Space complexity:
O(n)
. We use two additional arrays,pre
andsuf
, each of sizen
, to store our precomputed values.