https://blog.youkuaiyun.com/qq_36426073/article/details/90203633
实例 1052. 爱生气的书店老板
今天,书店老板有一家店打算试营业
customers.length
分钟。每分钟都有一些顾客(customers[i]
)会进入书店,所有这些顾客都会在那一分钟结束后离开。在某些时候,书店老板会生气。 如果书店老板在第
i
分钟生气,那么grumpy[i] = 1
,否则grumpy[i] = 0
。 当书店老板生气时,那一分钟的顾客就会不满意,不生气则他们是满意的。书店老板知道一个秘密技巧,能抑制自己的情绪,可以让自己连续
X
分钟不生气,但却只能使用一次。请你返回这一天营业下来,最多有多少客户能够感到满意的数量。
- 解法一 后缀和+滑动窗口
思路: 总和分成前后两部分A和B。A部分是从0到位置i的扫描和。B部分是从位置i+1的后缀和。求A+B的最大和即可。
例如:customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], X = 3
先求后缀和 S=[ 10 9 9 8 8 7 7 0 ]
那么,B=S[i+1]。
用滑动窗口求A部分。窗口右滑时,加上进入窗口的值,减去出窗口的值。
整体思路:
求后缀和S;
W = 0; 窗口值
ans = 0;结果
for(i < N){
if(i < X) W += 位置i的客户数;
else{
W += 入窗口的客户数;
W -= 出窗口的客户数;
}
ans = max(ans, W + S[i+1]);
}
- 解法二 滑动窗口
思路:结果分成两部分。不生气时的人数一定要全部累加上。此时,只需要求出窗口中,生气时的最大人数和即可。用滑动窗口法求窗口中生气时的最大人数和。
例如:customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], X = 3
不生气的位置 [1,0,1,2,1,1,7,5]
不生气的总人数 = 1 + 1 + 1 + 7 = 10
窗口中生气的人数 最大的位置 [1,0,1,2,1,1,7,5]
窗口中生气的最大人数和 = 1+5 = 6
思路:
W = 0;窗口值;
max_W = 0;最大窗口值;
ans = 0;结果值;
for(i < N){
if(不生气) ans += 人数;
else W += 入窗口生气的人数;
if(i >= X){
W -= 出窗口生气的人数;
}
max_W = max(max_W, W);
}
ans+ max_W是结果;
初始版本:
int maxSatisfied(vector<int>& customers, vector<int>& grumpy, int X) {
int s=customers.size();
int sum=0;
int maxdiff=0;
int ans=0;
for(int i=0;i<s;i++) sum+=(!grumpy[i])*customers[i];
int curr=0;
for(int i=0;i<X;i++) curr+=grumpy[i]*customers[i];
maxdiff=curr;
for(int i=X;i<s;i++){
curr+=grumpy[i]*customers[i]-grumpy[i-X]*customers[i-X];
maxdiff=max(curr,maxdiff);
}
return sum+maxdiff;
}
};
int maxSatisfied(vector<int>& customers, vector<int>& grumpy, int X) {
const int N = grumpy.size();
int W = 0;
int ans = 0;
int max_W = 0;
for(int i = 0;i<N;++i){
if(!grumpy[i]) ans += customers[i];
else W += grumpy[i] ? customers[i] : 0;
if(i >= X){
W -= grumpy[i-X] ? customers[i-X] : 0;
}
max_W = max(max_W,W);
}
return ans + max_W;
}
自己的:
class Solution {
public:
int maxSatisfied(vector<int>& customers, vector<int>& grumpy, int X) {
int satisfyNum = 0;
//int unsatisfyNum = 0; //放到循环里,每次初始化
int length = customers.size();
int maxunsatufy = 0;
int window = 0;//初始窗口值
//step 1 ,求出正常情况的满意顾客总数,和初始窗口数
for(int i = 0;i<length;i++)
{
if(grumpy[i]==0)
satisfyNum += customers[i];
else if(grumpy[i]==1&&i<X)//窗口初始条件
{
window += customers[i];
}
}
maxunsatufy = window; //此处有bug!!!如果不添加这句话的话
//step 2 ,运用滑动法求改变窗口,求出最大窗口值
//移动窗口时,出去的如果是生气的就消去!进来的是生气的就添加!如果不生气,则不影响
for (int i =X;i<length;i++)
{
if(grumpy[i]==1)//如果进入的是生气的,则添加
window += customers[i];
if(grumpy[i-X]==1)//如果退出的是生气的,则删除
window -= customers[i-X];
maxunsatufy = max(window,maxunsatufy);
}
return maxunsatufy + satisfyNum;
}
};
Bug: