滑动窗口,LeetCode 1052. 爱生气的书店老板

目录

一、题目

1、题目描述

2、接口描述

python3

cpp

3、原题链接

二、解题报告

1、思路分析

2、复杂度

3、代码详解

python3

cpp


一、题目

1、题目描述

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

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

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

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

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

2、接口描述

python3
class Solution:
    def maxSatisfied(self, customers: List[int], grumpy: List[int], minutes: int) -> int:
cpp
class Solution {
public:
    int maxSatisfied(vector<int>& customers, vector<int>& grumpy, int minutes) {

    }
};

3、原题链接

1052. 爱生气的书店老板


二、解题报告

1、思路分析

我们统计出客人总和s1,每个事件点不满意的客人数目cnt[i],cnt的和为s2

在cnt[]上维护一个长度为minute的滑动窗口,看最多能让多少不满意的变满意,记为res

答案就是s1 - s2 + res

2、复杂度

时间复杂度:O(n) 空间复杂度:O(n)

3、代码详解

python3
class Solution:
    def maxSatisfied(self, customers: List[int], grumpy: List[int], minutes: int) -> int:
        n = len(customers)
        cnt = [0] * n
        for i, x in enumerate(customers):
            if grumpy[i]:
                cnt[i] += x
        l, r, s = 0, -1, 0
        res = 0
        while r < n - 1:
            r += 1
            s += cnt[r]
            if r - l + 1 > minutes:
                s -= cnt[l]
                l += 1
            res = max(res, s)
        return sum(customers) - sum(cnt) + res
cpp
class Solution {
public:
    int maxSatisfied(vector<int>& customers, vector<int>& grumpy, int minutes) {
        int n = customers.size();
        vector<int> cnt(n);
        int s1 = 0, s2 = 0;
        for(int i = 0; i < n; i ++) {
            s1 += customers[i];
            if(grumpy[i])
                s2 += customers[i], cnt[i] += customers[i];
        }
        int l = 0, r = -1, s = 0, res = 0;
        while(r < n - 1){
            s += cnt[ ++ r];
            if(r - l + 1 > minutes) s -= cnt[l ++];
            res = max(res, s);
        }
        return s1 - s2 + res;
    }
};

滑动窗口是一种常用的算法技巧,可以用于解决一类问题,其中包括一些LeetCode上的题目。通过维护一个窗口,我们可以在线性时间内解决一些需要处理连续子数组或子字符串的问题。以下是一些常见的滑动窗口问题: 1. 最小覆盖子串(Minimum Window Substring):给定一个字符串S和一个字符串T,在S中找出包含T所有字符的最小子串。 2. 字符串的排列(Permutation in String):给定两个字符串s1和s2,判断s2是否包含s1的排列。 3. 找到字符串中所有字母异位词(Find All Anagrams in a String):给定一个字符串s和一个非空字符串p,找到s中所有是p的字母异位词的子串。 4. 替换后的最长重复字符(Longest Repeating Character Replacement):给定一个只包含大写英文字母的字符串s,你可以将一个字母替换成任意其他字母,使得包含重复字母的最长子串的长度最大化。 5. 至多包含两个不同字符的最长子串(Longest Substring with At Most Two Distinct Characters):给定一个字符串s,找出至多包含两个不同字符的最长子串的长度。 以上只是几个例子,滑动窗口可以应用于更多类型的问题。在解决这些问题时,我们通常使用两个指针来表示窗口的左右边界,并根据具体问题的要求移动窗口。在每次移动窗口时,我们可以更新窗口的状态,例如统计字符出现次数、判断窗口是否满足条件等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EQUINOX1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值