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
timedays before and after theithday, - The number of guards at the bank for the
timedays beforeiare non-increasing , and - The number of guards at the bank for the
timedays afteriare 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^50 <= 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
ihave non-increasing guards? - How many consecutive days starting at
ihave non-decreasing guards?
We can answer these questions for all days in linear time using two auxiliary arrays:
prearray: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] + 1ifsec[i-1] >= sec[i].- Otherwise, the streak is broken, so
pre[i]is reset to0.
sufarray: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] + 1ifsec[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,preandsuf, each of sizen, to store our precomputed values.