524,爱生气的书店老板

Some people choose to see the ugliness in this world. The disarray. I choose to see the beauty. 

一些人选择去看见这个世界的丑陋,混乱,我选择去发现美好。

问题描述

今天,书店老板有一家店打算试营业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.

 

提示:

  • 1<=X<=customers.length==grumpy.length<=20000

  • 0<=customers[i]<=1000

  • 0<=grumpy[i]<=1

 

窗口内的最大值

数组customers中的每个值表示每分钟内进来的客户量,数组grumpy中的每个值表示每分钟内老板是否生气。

 

  • 如果老板不生气,那么顾客肯定是满意的,我们先计算所有满意的数量。

  • 如果老板生气,那么顾客是不满意的,这些不满意的可以构成一个新的数组。而老板可以控制K分钟不生气,这个K分钟我们可以把它当做一个窗口,题目就转化为求这个新的数组中连续K个数字的最大和。

 

 

524,爱生气的书店老板

来看下代码

 1public int maxSatisfied(int[] customers, int[] grumpy, int X) {
2    int satisfied = 0;//先统计本来就满意的
3    int length = grumpy.length;
4    //新的数组,统计不满意的
5    int[] noSatisfied = new int[length];
6    for (int i = 0; i < length; i++) {
7        if (grumpy[i] == 0)
8            satisfied += customers[i];
9        else
10            noSatisfied[i] = customers[i] * grumpy[i];
11    }
12    //使用两个指针,类似于窗口的左边和右边
13    int left = 0;
14    int right = 0;
15    int max = 0;//记录窗口内的最大值
16    int sum = 0;//记录当前窗口内的值
17    for (; right < length; right++) {
18        sum += noSatisfied[right];
19        //如果窗口长度超过K,要减去窗口左边的值,同时
20        //窗口左边要往右移一步
21        if (right - left >= X) {
22            sum -= noSatisfied[left++];
23        }
24        //保存最大值
25        max = Math.max(max, sum);
26    }
27    //本来就满意的+老板控制情绪让顾客满意的
28    return satisfied + max;
29}

 

上面计算的时候我们使用了两个for循环,实际上我们还可以把他们合并成一个

 1public int maxSatisfied(int[] customers, int[] grumpy, int X) {
2    int satisfied = 0;//本来就满意的
3    int maxPretendSatisfied = 0;//最大抑制情绪满意的
4    int pretendSatisfied = 0;//窗口内抑制情绪满意的
5    for (int i = 0; i < grumpy.length; ++i) {
6        //如果grumpy[i]是0,表示顾客是满意的
7        if (grumpy[i] == 0) {
8            satisfied += customers[i];
9        } else {
10            //如果不等于0,表示顾客是不满意的,但老板可以控制自己的
11            //情绪,顾客表示假装满意
12            pretendSatisfied += customers[i];
13        }
14        //老板控制自己的情绪是有限的,这个范围我们可以把它看做是一个窗口,
15        //这个窗口是一直往右移动的,如果移除窗口的有不满意的,要减去
16        if (i >= X && grumpy[i - X] == 1) {
17            pretendSatisfied -= customers[i - X];
18        }
19        //保存通过抑制情绪使顾客满意的最大数量
20        maxPretendSatisfied = Math.max(maxPretendSatisfied, pretendSatisfied);
21    }
22    //最后返回本来就使顾客满意的数量+抑制情绪使顾客满意的数量
23    return satisfied + maxPretendSatisfied;
24}

 

总结

顾客本来就满意的只需要累加即可,而顾客不满意的,老板可以通过控制自己的情绪让顾客满意,我们只需要求这连续K个不满意的最大值,问题就很容易解决了。

 

524,爱生气的书店老板

443,滑动窗口最大值

407,动态规划和滑动窗口解决最长重复子数组

497,双指针验证回文串

447,双指针解旋转链表

 

 

截止到目前我已经写了500多道算法题了,为了方便大家阅读,我把部分算法题整理成了pdf文档,目前有800多页,大家可以在公众号中回复关键字“pdf”即可获取下载链接。

 

524,爱生气的书店老板你点的每个赞,我都认真当成了喜欢
上一篇:Delphi 版本的选择


下一篇:极客少年把爷爷的老打字机改造成酷炫乐器!疫情在家已经无聊成这样了?