/**
* @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]) total += customers[i];
}
// 然后滑出一个长度为 X 的窗口
// 这段是情绪控制区,所以原来不满意的顾客也变成满意的了
let l = 0,
r = 0;
while (r < X) {
if (grumpy[r]) total += customers[r];
r++;
}
let max = total;
// 窗口右移
// r 指针回到滑动窗口的右边界
r--;
while (r < customers.length - 1) {
// l 即将离开情绪控制区,如果原本是不满意的顾客,就恢复不满意啦
if (grumpy[l]) total -= customers[l];
l++;
r++;
// r 进入了情绪控制区,不满意顾客变成满意的了
if (grumpy[r]) total += customers[r];
if (total > max) max = total;
}
return max;
};
代码(简洁版本)
JavaScript Code
/**
* @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]) total += customers[i];
}
let max = total;
for (let i = 0; i < customers.length; i++) {
// 第一个滑动窗口,如果其中有不满意的顾客,将他们改成满意的
if (i < X) total += grumpy[i] ? customers[i] : 0;
// 滑动窗口右移中,(i - X, i] 这段就是滑动窗口
else {
// 左边界离开情绪控制区,如果原本是不满意的顾客,就恢复不满意啦
if (grumpy[i - X]) total -= customers[i - X];
// 右边界进入情绪控制区,不满意顾客变成满意的了
if (grumpy[i]) total += customers[i];
}
if (total > max) max = total;
}
return max;
};
代码(一次遍历的版本)
JavaScript Code
/**
* @param {number[]} customers
* @param {number[]} grumpy
* @param {number} X
* @return {number}
*/
var maxSatisfied = function (customers, grumpy, X) {
// 老板不生气时的所有满意顾客
let got = 0,
// 老板控制情绪时滑动窗口中增加的满意顾客,也就是滑动窗口中原本不满意的顾客
total = 0,
// 在滑动窗口移动过程中 total 的最大值
max = 0;
for (let i = 0; i < customers.length; i++) {
if (!grumpy[i]) got += customers[i];
// 第一个滑动窗口
if (i < X) total += grumpy[i] ? customers[i] : 0;
// 滑动窗口右移中,(i - X, i] 这段就是滑动窗口
else {
if (grumpy[i - X]) total -= customers[i - X];
if (grumpy[i]) total += customers[i];
}
if (total > max) max = total;
}
// 原本的满意顾客 + 情绪控制区最多能收揽的不满意顾客
return got + max;
};