指尖劃過的軌跡,藏着最細膩的答案~
題目:
有一個書店老闆,他的書店開了 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 \leq minutes \leq n \leq 2 \times 10^4$
$0 \leq customers[i] \leq 1000$
$grumpy[i] == 0$ or $1$
分析:
看到題目老闆可以連續minutes 分鐘不生氣,但卻只能使用一次,我們很容易可以想到使用定長滑動窗口,在窗口minutes中尋找最大和。
這樣就行了嗎?如果這個最大和正好在老闆不生氣的時候是不是就不一定符合題意了。為了解決這個問題,我們可以將最大和改為尋找生氣時的最大和maxSum,這可以使minutes發揮最大的作用。
另外,我們在遍歷過程中需要累加上老闆不生氣時的人數,最終加上maxSum即為答案。
AC代碼:
class Solution {
public:
int maxSatisfied(vector<int>& customers, vector<int>& grumpy, int minutes) {
int ans = 0, maxSum = 0, sum = 0;
int n = customers.size();
for (int i = 0; i < n; i++) {
// 進入窗口
if (grumpy[i]) {
sum += customers[i];
} else {
ans += customers[i];
}
int left = i - minutes + 1;
if (left < 0) {
continue;
}
// 更新答案
maxSum = max(maxSum, sum);
// 離開窗口
int out = customers[left];
if (grumpy[left]) {
sum -= out;
}
}
return ans + maxSum;
}
};