LeetCode 1052: Grumpy Bookstore Owner (Base Satisfied + Fixed Window Boost)
LeetCode 1052Sliding WindowToday we solve LeetCode 1052 - Grumpy Bookstore Owner.
Source: https://leetcode.com/problems/grumpy-bookstore-owner/
English
Problem Summary
We have customers[i] and owner mood grumpy[i]. If grumpy[i] = 0, those customers are always satisfied. The owner can suppress grumpiness for exactly minutes consecutive minutes. Return the maximum total satisfied customers.
Key Insight
Split the answer into two parts: (1) baseline customers already satisfied when grumpy[i] = 0, and (2) extra customers we can recover inside one length-minutes window where grumpy[i] = 1. So we only need the maximum fixed-window sum of recoverable customers.
Algorithm
- Compute baseline = sum of customers[i] when grumpy[i] == 0.
- Build sliding window on recoverable value (grumpy[i] == 1 ? customers[i] : 0).
- Track maximum window sum, answer = baseline + maxWindow.
Complexity Analysis
Time: O(n).
Space: O(1).
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public int maxSatisfied(int[] customers, int[] grumpy, int minutes) {
int n = customers.length;
int base = 0;
for (int i = 0; i < n; i++) {
if (grumpy[i] == 0) base += customers[i];
}
int window = 0, best = 0;
for (int i = 0; i < n; i++) {
if (grumpy[i] == 1) window += customers[i];
if (i >= minutes && grumpy[i - minutes] == 1) {
window -= customers[i - minutes];
}
best = Math.max(best, window);
}
return base + best;
}
}func maxSatisfied(customers []int, grumpy []int, minutes int) int {
n := len(customers)
base := 0
for i := 0; i < n; i++ {
if grumpy[i] == 0 {
base += customers[i]
}
}
window, best := 0, 0
for i := 0; i < n; i++ {
if grumpy[i] == 1 {
window += customers[i]
}
if i >= minutes && grumpy[i-minutes] == 1 {
window -= customers[i-minutes]
}
if window > best {
best = window
}
}
return base + best
}class Solution {
public:
int maxSatisfied(vector<int>& customers, vector<int>& grumpy, int minutes) {
int n = (int)customers.size();
int base = 0;
for (int i = 0; i < n; i++) {
if (grumpy[i] == 0) base += customers[i];
}
int window = 0, best = 0;
for (int i = 0; i < n; i++) {
if (grumpy[i] == 1) window += customers[i];
if (i >= minutes && grumpy[i - minutes] == 1) {
window -= customers[i - minutes];
}
best = max(best, window);
}
return base + best;
}
};class Solution:
def maxSatisfied(self, customers: list[int], grumpy: list[int], minutes: int) -> int:
base = sum(c for c, g in zip(customers, grumpy) if g == 0)
window = 0
best = 0
for i, (c, g) in enumerate(zip(customers, grumpy)):
if g == 1:
window += c
if i >= minutes and grumpy[i - minutes] == 1:
window -= customers[i - minutes]
best = max(best, window)
return base + bestvar maxSatisfied = function(customers, grumpy, minutes) {
const n = customers.length;
let base = 0;
for (let i = 0; i < n; i++) {
if (grumpy[i] === 0) base += customers[i];
}
let window = 0, best = 0;
for (let i = 0; i < n; i++) {
if (grumpy[i] === 1) window += customers[i];
if (i >= minutes && grumpy[i - minutes] === 1) {
window -= customers[i - minutes];
}
best = Math.max(best, window);
}
return base + best;
};中文
题目概述
给定 customers[i] 和店主情绪 grumpy[i]。当 grumpy[i]=0 时该分钟顾客天然满意。店主可以连续 minutes 分钟使用一次“冷静技巧”,把这段时间里的不满意顾客变为满意,求最多满意顾客数。
核心思路
答案拆成两部分:基础满意人数(本来就满意)+ 技巧窗口额外挽回人数(只统计原本 grumpy=1 的分钟)。这样问题变成固定长度滑动窗口取最大和。
算法步骤
- 先累计 grumpy[i]==0 的顾客数作为 base。
- 用窗口维护当前长度为 minutes 的“可挽回顾客数”。
- 窗口右移时加入新位置、移除旧位置,维护最大值 best。
- 最终返回 base + best。
复杂度分析
时间复杂度:O(n)。
空间复杂度:O(1)。
多语言参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public int maxSatisfied(int[] customers, int[] grumpy, int minutes) {
int n = customers.length;
int base = 0;
for (int i = 0; i < n; i++) {
if (grumpy[i] == 0) base += customers[i];
}
int window = 0, best = 0;
for (int i = 0; i < n; i++) {
if (grumpy[i] == 1) window += customers[i];
if (i >= minutes && grumpy[i - minutes] == 1) {
window -= customers[i - minutes];
}
best = Math.max(best, window);
}
return base + best;
}
}func maxSatisfied(customers []int, grumpy []int, minutes int) int {
n := len(customers)
base := 0
for i := 0; i < n; i++ {
if grumpy[i] == 0 {
base += customers[i]
}
}
window, best := 0, 0
for i := 0; i < n; i++ {
if grumpy[i] == 1 {
window += customers[i]
}
if i >= minutes && grumpy[i-minutes] == 1 {
window -= customers[i-minutes]
}
if window > best {
best = window
}
}
return base + best
}class Solution {
public:
int maxSatisfied(vector<int>& customers, vector<int>& grumpy, int minutes) {
int n = (int)customers.size();
int base = 0;
for (int i = 0; i < n; i++) {
if (grumpy[i] == 0) base += customers[i];
}
int window = 0, best = 0;
for (int i = 0; i < n; i++) {
if (grumpy[i] == 1) window += customers[i];
if (i >= minutes && grumpy[i - minutes] == 1) {
window -= customers[i - minutes];
}
best = max(best, window);
}
return base + best;
}
};class Solution:
def maxSatisfied(self, customers: list[int], grumpy: list[int], minutes: int) -> int:
base = sum(c for c, g in zip(customers, grumpy) if g == 0)
window = 0
best = 0
for i, (c, g) in enumerate(zip(customers, grumpy)):
if g == 1:
window += c
if i >= minutes and grumpy[i - minutes] == 1:
window -= customers[i - minutes]
best = max(best, window)
return base + bestvar maxSatisfied = function(customers, grumpy, minutes) {
const n = customers.length;
let base = 0;
for (let i = 0; i < n; i++) {
if (grumpy[i] === 0) base += customers[i];
}
let window = 0, best = 0;
for (let i = 0; i < n; i++) {
if (grumpy[i] === 1) window += customers[i];
if (i >= minutes && grumpy[i - minutes] === 1) {
window -= customers[i - minutes];
}
best = Math.max(best, window);
}
return base + best;
};
Comments