LeetCode: 1052. 愛生氣的書店老闆(中等)

LeetCode刷題記錄發表於2021-01-05

題目描述

今天,書店老闆有一家店打算試營業 customers.length 分鐘。每分鐘都有一些顧客(customers[i])會進入書店,所有這些顧客都會在那一分鐘結束後離開。

在某些時候,書店老闆會生氣。 如果書店老闆在第 i 分鐘生氣,那麼 grumpy[i] = 1,否則 grumpy[i] = 0。 當書店老闆生氣時,那一分鐘的顧客就會不滿意,不生氣則他們是滿意的。

書店老闆知道一個祕密技巧,能抑制自己的情緒,可以讓自己連續 X 分鐘不生氣,但卻只能使用一次。

請你返回這一天營業下來,最多有多少客戶能夠感到滿意的數量。

示例:
輸入:customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], X = 3
輸出:16
解釋:
書店老闆在最後 3 分鐘保持冷靜。
感到滿意的最大客戶數量 = 1 + 1 + 1 + 1 + 7 + 5 = 16.

提示:

  • 1 <= X <= customers.length == grumpy.length <= 20000
  • 0 <= customers[i] <= 1000
  • 0 <= grumpy[i] <= 1

題解

滿意的數量 = 老闆正常不生氣的顧客滿意數量(grumpy[i] 原本為0) + 老闆使用祕密技巧獲得顧客滿意的數量(從 grumpy[i] 從1 -> 0)。

  • 老闆正常不生氣的獲得顧客的滿意數量使用for迴圈計算grumpy[i]為0時的customer[i]值
  • 老闆使用祕密技巧獲得顧客滿意的數量採用滑動視窗計算,統計量為max
    a) 視窗擴大,將grumpy[i]為1的customer[i]加進來
    b) 若視窗大於X時,收縮視窗,減去grumpy[i-X]為1的customer[i-X]
    c) 若當前視窗內新增滿意客戶數count的值大於max,則更新max
    返回 base + max
class Solution {
public:
    int maxSatisfied(vector<int>& customers, vector<int>& grumpy, int X) {
        int max=0,base=0;//max記錄通過抑制脾氣改變的從不滿意到滿意的最大客戶,base記錄原先就是滿意的客戶數,count當前視窗內新增滿意客戶數
        for(int i=0,count=0;i<grumpy.size();i++)
        {
             if(grumpy[i]==0) base += customers[i];
             if(i < X && grumpy[i]==1)//滑動視窗小於X時 並且這時候會生氣就加入count
                count += customers[i];
             // 滑動視窗右移中,(i - X, i] 這段就是滑動視窗
             else if(i >= X)
             {
                 //滑動視窗左端移出右端移進,移出時若老闆生氣,則減去此時顧客數,移進時若老闆生氣,則加上此時顧客數,
                 if(i-X >= 0 && grumpy[i-X]==1)
                 count -= customers[i-X];
                 if(grumpy[i]==1)
                 count += customers[i];
             }
             if(count > max) max = count;//更新max值
             
            
        }
        return base + max;
        
    }
};

複雜度分析
時間複雜度:O(N),N 為陣列長度。
空間複雜度:O(1)。

參考

c++ 滑動視窗
1052. 愛生氣的書店老闆【滑動視窗、JavaScript】
滑動視窗-愛生氣的書店老闆

相關文章