Grumpy Bookstore Owner
Customers arrive each minute; when the owner is grumpy those customers are lost. Once, for minutes consecutive minutes , the owner can stay calm. Maximize satisfied customers: add a baseline of already-happy minutes to the best fixed window of rescued grumpy-minute customers.
Constraints
- 1 ≤ minutes ≤ customers.length == grumpy.length ≤ 2 × 104
- 0 ≤ customersi ≤ 1000
- grumpyi is either 0 or 1
Example
customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], minutes = 316Explanation Calm minutes 5–7 to rescue 6 customers; baseline 10 + 6 = 16.
In plain terms
- Grumpy
- In a bad mood — here, a minute where the owner is grumpy means every customer who arrives that minute leaves unhappy and does not count as satisfied.
Baseline + best rescued grumpy window
First window rescues 0 grumpy customers (only index 1 is grumpy with 0).
What happens in this step
window = [0, 2] customers [1, 0, 1] grumpy [0, 1, 0] Only index 1 is a grumpy minute, and its customer count is 0, so calming it rescues nothing. windowRescued = 0 — bestRescued = 0 so far.
Steps to visualize
- Sum customers on minutes when the owner is already calm — that is the baseline.
- Place a fixed window of length minutes and sum customers only on grumpy minutes.
- That window sum is the customers you can rescue by staying calm.
- Slide the rescue window and keep the maximum rescued total.
- Answer is baseline plus the best rescue window.
Walk through the code
Same walkthrough, now with the code. Press Next to move one step and watch which lines run.
First window rescues 0 grumpy customers (only index 1 is grumpy with 0).
What happens in this step
window = [0, 2] customers [1, 0, 1] grumpy [0, 1, 0] Only index 1 is a grumpy minute, and its customer count is 0, so calming it rescues nothing. windowRescued = 0 — bestRescued = 0 so far.
Solution
function maxSatisfied(customers, grumpy, minutes) {
const n = customers.length;
let baseline = 0;
for (let i = 0; i < n; i++) {
if (grumpy[i] === 0) baseline += customers[i];
}
let windowRescued = 0;
for (let i = 0; i < minutes; i++) {
if (grumpy[i] === 1) windowRescued += customers[i];
}
let bestRescued = windowRescued;
for (let right = minutes; right < n; right++) {
if (grumpy[right] === 1) windowRescued += customers[right];
const left = right - minutes;
if (grumpy[left] === 1) windowRescued -= customers[left];
bestRescued = Math.max(bestRescued, windowRescued);
}
return baseline + bestRescued;
}- Time
- O(n)
- Space
- O(1)
Test cases
| Input | Expected | Covers |
|---|---|---|
customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], minutes = 3 | 16 | Docstring example |
customers = [5], grumpy = [1], minutes = 1 | 5 | Single minute |
customers = [3, 4, 5], grumpy = [0, 0, 0], minutes = 1 | 12 | Owner never grumpy |
customers = [3, 4, 5], grumpy = [1, 1, 1], minutes = 2 | 9 | Always grumpy — technique covers max window |
customers = [1, 2, 3], grumpy = [1, 0, 1], minutes = 3 | 6 | minutes equals full array length |
customers = [4, 4, 4, 4], grumpy = [1, 1, 1, 1], minutes = 2 | 8 | Identical counts, always grumpy |
customers = [1,2,3,1,1,7,5,2], grumpy = [0,0,1,1,0,1,0,0], minutes = 3 | 19 | Baseline 11 + best rescue 8 |