题目描述
思路解析动画文字版
记住「绿色白赚记 base,红色用一个宽 minutes 的窗口挑挽回最多的一段」,下面每帧都在套它。
先给每分钟上色:绿色是老板不生气的分钟(顾客白白满意),红色是生气的分钟(顾客流失)。技巧能连续盖住 3 分钟,把这段窗口内红色分钟的损失抢回来。
第 0 分钟绿色(不生气),1 位顾客白赚,base 累加到 1。
第 1 分钟红色(生气),0 位顾客流失,先不计入 base——等会儿看技巧能不能盖到它。
第 2 分钟绿色(不生气),1 位顾客白赚,base 累加到 2。
第 3 分钟红色(生气),2 位顾客流失,先不计入 base——等会儿看技巧能不能盖到它。
第 4 分钟绿色(不生气),1 位顾客白赚,base 累加到 3。
第 5 分钟红色(生气),1 位顾客流失,先不计入 base——等会儿看技巧能不能盖到它。
第 6 分钟绿色(不生气),7 位顾客白赚,base 累加到 10。
第 7 分钟红色(生气),5 位顾客流失,先不计入 base——等会儿看技巧能不能盖到它。
把冷静技巧盖在第 0~2 分钟(高亮窗口)。这段里原本生气流失的顾客被挽回,共 0 位。
0 没超过当前最优 best = 0,窗口继续右滑。
把冷静技巧盖在第 1~3 分钟(高亮窗口)。这段里原本生气流失的顾客被挽回,共 2 位。
2 比之前最优更高,刷新 best = 2,记下窗口起点 1。
把冷静技巧盖在第 2~4 分钟(高亮窗口)。这段里原本生气流失的顾客被挽回,共 2 位。
2 没超过当前最优 best = 2,窗口继续右滑。
把冷静技巧盖在第 3~5 分钟(高亮窗口)。这段里原本生气流失的顾客被挽回,共 3 位。
3 比之前最优更高,刷新 best = 3,记下窗口起点 3。
把冷静技巧盖在第 4~6 分钟(高亮窗口)。这段里原本生气流失的顾客被挽回,共 1 位。
1 没超过当前最优 best = 3,窗口继续右滑。
把冷静技巧盖在第 5~7 分钟(高亮窗口)。这段里原本生气流失的顾客被挽回,共 6 位。
6 比之前最优更高,刷新 best = 6,记下窗口起点 5。
最优是把冷静技巧盖在第 5~7 分钟,挽回 6 位。加上白赚的 base 10,最多满意顾客 = 16。
边界先想清:从不生气、技巧能盖全程、技巧时长为 0。
面试重点:认出「定长窗口最大和 + 固定基底」这个结构。
参考代码
from typing import Listclass Solution: def maxSatisfied(self, customers: List[int], grumpy: List[int], minutes: int) -> int: base = sum(c for c, g in zip(customers, grumpy) if g == 0) extra = best = 0 for i, c in enumerate(customers): if grumpy[i]: extra += c if i >= minutes and grumpy[i - minutes]: extra -= customers[i - minutes] best = max(best, extra) return base + best复杂度
- 时间:O(n),窗口增量滑动,一遍扫完
- 空间:O(1),只用 base/extra/best 三个变量
易错点
面试追问把动画讲成自己的话
追问这题滑动窗口和「定长子数组最大和」是一回事吗?
追问为什么不用前缀和?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
尽可能使字符串相等
LeetCode 1208 · 中等 · 沿着 滑动窗口套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题