题目描述
今天,书店老板有一家店打算试营业
customers.length
分钟。每分钟都有一些顾客(customers[i]
)会进入书店,所有这些顾客都会在那一分钟结束后离开。
在某些时候,书店老板会生气。 如果书店老板在第 i 分钟生气,那么 grumpy[i] = 1,否则 grumpy[i] = 0。 当书店老板生气时,那一分钟的顾客就会不满意,不生气则他们是满意的。
书店老板知道一个秘密技巧,能抑制自己的情绪,可以让自己连续 X 分钟不生气,但却只能使用一次。
请你返回这一天营业下来,最多有多少客户能够感到满意的数量。
示例
输入:customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], X = 3
输出:16
解释:
书店老板在最后 3 分钟保持冷静。
感到满意的最大客户数量 = 1 + 1 + 1 + 1 + 7 + 5 = 16.
解题思路
通过题意可知,有两个数组,一个是customers数组,代表每分钟进入书店的顾客数量,一个是grumpy数组,其元素值为1或0,代表老板在当前时刻生气或不生气。X则代表老板抑制自己情绪的时间,在此时间段内老板可以保证不生气,即在此区间段内所有顾客都会感到满意。我们要做的就是在上述条件下老板最多让多少顾客感到满意。
题干中给出区间范围,我们自然能够想到利用滑动窗口
在解题。
class Solution {
public int maxSatisfied(int[] customers, int[] grumpy, int X) {
//maxRes用于记录最大满意人数,curRes用于记录当前区间内满意人数
int maxRes = 0,curRes = 0;
for(int i = 0; i < customers.length; i ++){
if(grumpy[i] == 0) {
maxRes += customers[i];
//为了减少后续对于grumpy是否为1的判断
customers[i] = 0;
};
}
curRes = maxRes;
for(int i = 0; i < customers.length; i ++){
if( i >= X ) {
//此时表面区间已经超过窗口大小,故将区间最左侧人数减去
curRes -= customers[i-X];
}
//累加新纳入区间的人数
curRes += customers[i];
maxRes = Math.max(curRes,maxRes);
}
return maxRes;
}
}
备注:
这里解释当grumpy[i]为0时,将customer[i]置为0的原因。首先for循环内,我们将grumpy为0的所有时刻可以服务满意的顾客进行了累加,即为老板最少可以服务满意顾客的数量。然后再通过设置X的区间,去寻找最大满意顾客数量。如果没有customer[i] = 0的操作。我们在计算当前curRes时,即当前区间内最大满意顾客数量,需要判断当前窗口右边界的i对应的grumpy[i]是否为1,只有为1的时候,即老板生气,我们才能将customer[i]累加到curRes中。同理,对于窗口左边界,我们需要判断grumpy[i]是否为1,只有为1表示老板生气时,我们才需要将此时刻的顾客从curRes中减去。因此需要多余的两个if语句进行判断。但如果将所有grumpy[i]为0所对应的customer[i]都置为0时,则左右边界无须再进行判断,直接加上或者减去customer[i]的值即可,值为0不会对cusRes造成影响。