🧠
Sliding Window (Prefix Sum + Window Scan)
💡 This approach improves efficiency by precomputing the base satisfaction and then using a sliding window to find the best window to convert grumpy minutes.
Intuition
Calculate base satisfaction from non-grumpy minutes, then slide a window of size X over the array to find the maximum extra customers gained by converting grumpy minutes within that window.
Algorithm
- Calculate base satisfaction from all non-grumpy minutes.
- Create an array extra where extra[i] = customers[i] if grumpy[i] == 1 else 0.
- Use a sliding window of size X over extra to find the maximum sum of extra customers.
- Return base satisfaction plus the maximum extra sum found.
💡 Sliding window avoids repeated summation by adding the new element and removing the old one as the window moves.
def maxSatisfied(customers, grumpy, X):
n = len(customers)
base_satisfied = 0
extra = [0] * n
for i in range(n):
if grumpy[i] == 0:
base_satisfied += customers[i]
else:
extra[i] = customers[i]
window_sum = sum(extra[:X])
max_extra = window_sum
for i in range(X, n):
window_sum += extra[i] - extra[i - X]
if window_sum > max_extra:
max_extra = window_sum
return base_satisfied + max_extra
# Driver code
if __name__ == '__main__':
customers = [1,0,1,2,1,1,7,5]
grumpy = [0,1,0,1,0,1,0,1]
X = 3
print(maxSatisfied(customers, grumpy, X)) # Expected output: 16
Line Notes
extra = [0] * nInitialize array to hold extra customers from grumpy minutes
if grumpy[i] == 0:Add to base satisfaction if owner is not grumpy
window_sum = sum(extra[:X])Calculate initial window sum for first X elements
window_sum += extra[i] - extra[i - X]Slide window by adding new element and removing old
public class Solution {
public int maxSatisfied(int[] customers, int[] grumpy, int X) {
int n = customers.length;
int baseSatisfied = 0;
int[] extra = new int[n];
for (int i = 0; i < n; i++) {
if (grumpy[i] == 0) {
baseSatisfied += customers[i];
} else {
extra[i] = customers[i];
}
}
int windowSum = 0;
for (int i = 0; i < X; i++) {
windowSum += extra[i];
}
int maxExtra = windowSum;
for (int i = X; i < n; i++) {
windowSum += extra[i] - extra[i - X];
if (windowSum > maxExtra) {
maxExtra = windowSum;
}
}
return baseSatisfied + maxExtra;
}
public static void main(String[] args) {
Solution sol = new Solution();
int[] customers = {1,0,1,2,1,1,7,5};
int[] grumpy = {0,1,0,1,0,1,0,1};
int X = 3;
System.out.println(sol.maxSatisfied(customers, grumpy, X)); // Expected: 16
}
}
Line Notes
int[] extra = new int[n];Array to store extra customers from grumpy minutes
if (grumpy[i] == 0)Add to base satisfaction if owner is not grumpy
for (int i = 0; i < X; i++)Calculate initial window sum for first X elements
windowSum += extra[i] - extra[i - X];Slide window by adding new and removing old element
#include <iostream>
#include <vector>
using namespace std;
int maxSatisfied(vector<int>& customers, vector<int>& grumpy, int X) {
int n = customers.size();
int baseSatisfied = 0;
vector<int> extra(n, 0);
for (int i = 0; i < n; i++) {
if (grumpy[i] == 0) {
baseSatisfied += customers[i];
} else {
extra[i] = customers[i];
}
}
int windowSum = 0;
for (int i = 0; i < X; i++) {
windowSum += extra[i];
}
int maxExtra = windowSum;
for (int i = X; i < n; i++) {
windowSum += extra[i] - extra[i - X];
if (windowSum > maxExtra) {
maxExtra = windowSum;
}
}
return baseSatisfied + maxExtra;
}
int main() {
vector<int> customers = {1,0,1,2,1,1,7,5};
vector<int> grumpy = {0,1,0,1,0,1,0,1};
int X = 3;
cout << maxSatisfied(customers, grumpy, X) << endl; // Expected: 16
return 0;
}
Line Notes
vector<int> extra(n, 0);Initialize vector to hold extra customers from grumpy minutes
if (grumpy[i] == 0)Add to base satisfaction if owner is not grumpy
for (int i = 0; i < X; i++)Calculate initial window sum for first X elements
windowSum += extra[i] - extra[i - X];Slide window by adding new and removing old element
function maxSatisfied(customers, grumpy, X) {
const n = customers.length;
let baseSatisfied = 0;
const extra = new Array(n).fill(0);
for (let i = 0; i < n; i++) {
if (grumpy[i] === 0) {
baseSatisfied += customers[i];
} else {
extra[i] = customers[i];
}
}
let windowSum = 0;
for (let i = 0; i < X; i++) {
windowSum += extra[i];
}
let maxExtra = windowSum;
for (let i = X; i < n; i++) {
windowSum += extra[i] - extra[i - X];
if (windowSum > maxExtra) {
maxExtra = windowSum;
}
}
return baseSatisfied + maxExtra;
}
// Test
const customers = [1,0,1,2,1,1,7,5];
const grumpy = [0,1,0,1,0,1,0,1];
const X = 3;
console.log(maxSatisfied(customers, grumpy, X)); // Expected: 16
Line Notes
const extra = new Array(n).fill(0);Initialize array to hold extra customers from grumpy minutes
if (grumpy[i] === 0)Add to base satisfaction if owner is not grumpy
for (let i = 0; i < X; i++)Calculate initial window sum for first X elements
windowSum += extra[i] - extra[i - X];Slide window by adding new and removing old element
We do a single pass to compute base and extra arrays, then a sliding window pass over extra, each O(n).
💡 For n=10^5, this means about 2*10^5 operations, which is efficient for interviews.
Interview Verdict: Accepted / Efficient
This approach is efficient and practical for large inputs, suitable for coding interviews.