【LeetCode】1052. Grumpy Bookstore Owner

本文介绍了如何使用滑动窗口算法解决LeetCode上的一个问题,即在有限时间内保持书店老板心情平和,最大化满足的顾客数量。通过遍历和更新grumpy数组影响的customers数组,找到满足条件的连续子序列和的最大值。
摘要由CSDN通过智能技术生成

思路:利用滑动窗口

        如果老板没有“灵丹妙药”,则在给定 customers 和 grumpy 数组的前提下满意的顾客总数量是唯一确定的;但有了此“药”后,老板便能在指定的 minutes 时间间隔内保持心态平和,从而可能使满意顾客总数量的增加;又因为 minutes 长度的时间间隔从哪个时刻(第几分钟)开始不确定,因而就存在满意顾客数量的最大值。因而:

  1. 先计算出没有“灵丹妙药”情况下满意顾客的总数量,赋值给 res;
  2. 利用 grumpy 的值( 0 或 1 )更新 customers 的值,即令 customers 只显示第 i 分钟不满意的顾客量,以便将原问题转化为求解 minutes 大小的 customers 的连续子序列和的最大值 maxx
    1. 如果 grumpy[i] = 0 (老板慈祥中,已包含进 res),置 customers[i] = 0;
    2. 反之,customers[i] 的值不变;
  3. 遍历 customers 数组得 maxx,返回原先满意的顾客总量 res + 老板药后新增的顾客量 maxx。

Input : customers = [ 1,0,1,2,1,1,7,5 ],grumpy = [ 0,1,0,1,0,1,0,1 ],minutes = 3

i01234567
customers[i]10121175
grumpy[i]01010101
customers[i] * grumpy[i]00020105

上述测试用例 res = 1 + 1 + 1 + 7 = 10

所有滑动窗口对应 customers 的值集为 {0, 0, 0}, {0, 0, 2}, {0, 2, 0}, {2, 0, 1}, {0, 1, 0}, {1, 0, 5}, 故 maxx = 1 + 0 + 5 = 6

class Solution {
public:
    int maxSatisfied(vector<int>& customers, vector<int>& grumpy, int minutes) {
        int n = customers.size(), res = 0, maxx = 0;
        for(int i = 0; i < n; i++) {
            if(grumpy[i] == 0) res += customers[i];
            customers[i] *= grumpy[i];
        }
        for(int i = 0; i <= n - minutes; i++) {
            int sum = accumulate(customers.begin() + i, customers.begin() + i + minutes, 0);
            if(sum > maxx) maxx = sum;
        }
        return res + maxx;
    }
};

稍作优化

使用变量 temp 存储长度为 minutes 的连续子序列的和。

参考https://leetcode.com/problems/grumpy-bookstore-owner/discuss/299237/C%2B%2B-Sliding-Window

class Solution {
public:
    int maxSatisfied(vector<int>& customers, vector<int>& grumpy, int minutes) {
        int n = customers.size(), res = 0, maxx = 0, temp = 0;
        for (int i = 0; i < n; i++) {
            if (grumpy[i] == 0)
                res += customers[i];
            temp += grumpy[i] * customers[i];
            if (i >= minutes)
                temp -= grumpy[i - minutes] * customers[i - minutes];
            maxx = max(temp, maxx);
        }
        return res + maxx;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值