【刷题打卡】1052. 爱生气的书店老板

136 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、题目描述:

1052. 爱生气的书店老板 - 力扣(LeetCode) (leetcode-cn.com)

有一个书店老板,他的书店开了 n 分钟。每分钟都有一些顾客进入这家商店。给定一个长度为 n 的整数数组 customers ,其中 customers[i] 是在第 i 分钟开始时进入商店的顾客数量,所有这些顾客在第 i 分钟结束后离开。

在某些时候,书店老板会生气。 如果书店老板在第 i 分钟生气,那么 grumpy[i] = 1,否则 grumpy[i] = 0

当书店老板生气时,那一分钟的顾客就会不满意,若老板不生气则顾客是满意的。

书店老板知道一个秘密技巧,能抑制自己的情绪,可以让自己连续 minutes 分钟不生气,但却只能使用一次。

请你返回 这一天营业下来,最多有多少客户能够感到满意 。  

示例 1:

输入:customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], minutes = 3
输出:16
解释:书店老板在最后 3 分钟保持冷静。
感到满意的最大客户数量 = 1 + 1 + 1 + 1 + 7 + 5 = 16.

示例 2:

输入:customers = [1], grumpy = [0], minutes = 1
输出:1

 

提示:

  • n == customers.length == grumpy.length
  • 1 <= minutes <= n <= 2 * 10^4
  • 0 <= customers[i] <= 1000
  • grumpy[i] == 0 or 1

二、思路分析:

  • 计算老板不生气时的顾客数总和total
  • 维护一个长度为X滑动窗口,该窗口代表老板的冷静期,结果需要算上该冷静期内的所有顾客数
  • 当窗口扩大时,计算窗口内是否有老板生气的元素,即grumpy[i]值为1,有的话假设老板在该窗口冷静,则total加上当前i索引对应的顾客数;
  • 当窗口缩小时,即窗口超过X个元素进行窗口缩小,如果从窗口移出的元素grumpy[i]的值为1,说明刚才total已经加上了该i索引的顾客数,所以此时需要减掉i索引对应的顾客数
  • 窗口每次移动时,取total的最大值即可

三、AC 代码:

/**
 * @param {number[]} customers
 * @param {number[]} grumpy
 * @param {number} X
 * @return {number}
 */
var maxSatisfied = function(customers, grumpy, X) {
    // 不生气时所有的顾客满意数
    let total = 0;
    for (let i = 0; i < customers.length; i++) {
        if (grumpy[i] === 0) {
            total += customers[i];
        }
    }

    let result = total;

    let left = 0;
    let right = 0;

    // 双指针维护长度为X的一个窗口
    while (right < customers.length) {
        // 新加入窗口的元素看是否是生气的,是的话加上该顾客人数
        if (grumpy[right]) {
            total += customers[right];
        }

        // 缩小窗口,缩小的元素是生气的,那减去该顾客的人数
        if (right - left == X) {
            if (grumpy[left]) {
              total -= customers[left];
            }
            left++;
        }

        right++;
        // 取最大值
        result = Math.max(result, total);
    }

    return result;
};