1052 爱生气的书店老板(滑动窗口)

it2025-04-18  4

1. 问题描述:

今天,书店老板有一家店打算试营业 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. 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/grumpy-bookstore-owner

2. 思路分析:

① 分析题目可以知道当grumpy[i] = 0的时候顾客肯定是满意的,所以我们在遍历数组的时候可以累加这些顾客的数量,第二个是我们需要求解出在len(customers)范围之内连续长度为X对应的customers的最大值是多少,所以我们是要求解出所有长度为X的连续区间的不满意的数目然后选择使得区间最大的那个使得这些顾客满意,这就相当于是使用了技能了,所以我们只要把这两部分:当老板不生气的时候满意的顾客数目 + 使用技能使得长度为X的连续区间的满意的顾客数目累加起来即可,因为要求解出所有长度为X的连续区间所以这是一个滑动窗口的问题,对于滑动窗口的问题我们可以分析题目根据具体的条件来进行窗口的滑动:

一开始的时候l = r = 0,然后向右扩展右边的窗口,使得窗口扩大,等到窗口不满足题目条件的时候那么左窗口往右边进行扩展也就是缩小整个窗口,基于这个思路我们可以对大部分的滑动窗口使用这样的模板来解决的,力扣中的1208题也是使用了滑动窗口的模板的思路来求解的,可以对照着理解就可以发现其中的套路了

② 除了上面的滑动窗口之外,发现了力扣中的另外一种滑动窗口的思路也是非常棒的,以后在遇到这样的题目的时候可以借鉴一下类似的思路:

首先遍历customers数组,累加老板在不生气的时候顾客满意的人数,并且当grumpy[i] = 0累加customers[i]之后将customers[i]置为0这样在后面滑动窗口的时候就可以累加使用技能使得顾客满意的数目了,第二步是计算所有长度为X的窗口的,这里使用到一个技巧就是不必暴力计算所有长度为X的数组,我们可以在一开始的时候计算customers[0:X]区间的值,然后依次进行窗口的滑动,比如customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], X = 3也即t = customers[0:3]的区间的值,然后t + customers[3] - customers[0],这相当于窗口是往右边滑动了一个单位了,也就是计算的是customers[1:4]区间的值... 对于循环的每一次都是这样进行滑动,这样我们就可以在滑动的时候计算出最大的窗口的值是多少了,最后将这两部分的值累加起来就是答案了

3. 代码如下:

滑动窗口模板:

from typing import List class Solution: def maxSatisfied(self, customers: List[int], grumpy: List[int], X: int) -> int: l, r, t1, t2 = 0, 0, 0, 0 res = 0 while r < len(customers): res += customers[r] if grumpy[r] == 0 else 0 t1 += customers[r] if grumpy[r] == 1 else 0 # 当窗口不满足题目条件的时候缩小左边的窗口 if r - l + 1 > X: t1 -= customers[l] if grumpy[l] == 1 else 0 l += 1 r += 1 t2 = max(t1, t2) return res + t2

第二种思路:

from typing import List class Solution: def maxSatisfied(self, customers: List[int], grumpy: List[int], X: int) -> int: not_angry = 0 for i in range(len(customers)): if grumpy[i] == 0: not_angry += customers[i] customers[i] = 0 # 计算出第一个滑动窗口 t1 = sum(customers[0: X]) t2 = t1 # 窗口的滑动 for i in range(1, len(customers) - X + 1): t1 = t1 + customers[i + X - 1] - customers[i - 1] t2 = max(t1, t2) # 将两部分的结果加起来 return not_angry + t2

 

最新回复(0)