链接
https://leetcode-cn.com/problems/grumpy-bookstore-owner/
耗时
解题:40 min
题解:23 min
题意
今天,书店老板有一家店打算试营业 customers.length 分钟。每分钟都有一些顾客(customers[i])会进入书店,所有这些顾客都会在那一分钟结束后离开。
在某些时候,书店老板会生气。 如果书店老板在第 i 分钟生气,那么 grumpy[i] = 1,否则 grumpy[i] = 0。 当书店老板生气时,那一分钟的顾客就会不满意,不生气则他们是满意的。
书店老板知道一个秘密技巧,能抑制自己的情绪,可以让自己连续 X 分钟不生气,但却只能使用一次。
请你返回这一天营业下来,最多有多少客户能够感到满意的数量。
提示:
- 1 <= X <= customers.length == grumpy.length <= 20000
- 0 <= customers[i] <= 1000
- 0 <= grumpy[i] <= 1
思路
grumpy[i] = 0 老板不生气的时候顾客是满意的,那就无所谓抑制,所以只需要管 grumpy[i] = 1 老板生气的时候,让客户能够感到满意的数量最大即可。因此,找到长度为 X 的连续子数组,使得连续子数组中所有 grumpy[i] = 1 的位置 i 对应的 customers[i] 的和最大,即是客户能够感到满意的数量最大。这最大的和加上老板不生气时顾客的数量总和(所有 grumpy[i] = 0 的位置 i 对应的 customers[i] 的和)即是答案。
滑动窗口长度固定为 X,把窗口内 grumpy[i] = 1 的位置 i 对应的 customers[i] 加起来 记作 win1cus,窗口每次向右滑动一位更新这个 win1cus,找到 win1cus 最大值,然后加上所有 grumpy[i] = 0 的位置 i 对应的 customers[i] 的和作为答案返回。
时间复杂度: O ( n ) O(n) O(n)
AC代码
class Solution {
public:
int maxSatisfied(vector<int>& customers, vector<int>& grumpy, int X) {
int win1cus = 0;
int n = customers.size();
int l = 1, r = 0;
for(; r < X; ++r) {
if(grumpy[r] == 1) {
win1cus += customers[r];
}
}
int max1cus = win1cus;
while(r < n) {
if(grumpy[l-1] == 1) {
win1cus -= customers[l-1];
}
if(grumpy[r] == 1) {
win1cus += customers[r];
}
max1cus = max(max1cus, win1cus);
l++;
r++;
}
int ans = max1cus;
for(int i = 0; i < n; ++i) {
if(grumpy[i] == 0) {
ans += customers[i];
}
}
return ans;
}
};