單調棧算法(leetcode 1124 表現良好的最長時間段)

【單調棧的定義】

滿足單調性的棧結構

【圖例】

【leetcode 1124 表現良好的最長時間段】

【題目】

給你一份工作時間表 hours,上面記錄着某一位員工每天的工作小時數。

我們認爲當員工一天中的工作小時數大於 8 小時的時候,那麼這一天就是「勞累的一天」。

所謂「表現良好的時間段」,意味在這段時間內,「勞累的天數」是嚴格 大於「不勞累的天數」。

請你返回「表現良好時間段」的最大長度。

 

示例 1:

輸入:hours = [9,9,6,0,6,6,9]
輸出:3
解釋:最長的表現良好時間段是 [9,9,6]。
 

提示:

1 <= hours.length <= 10000
0 <= hours[i] <= 16

【分析】

第一步:根據時間是否大於8,將每一天的工作小時數量化成1與-1,這樣有利於後續的計算。

題目中的[9,9,6,0,6,6,9]被量化爲[1,1,-1,-1,-1,-1,1]。這樣,理解題意,可以看出我們需要得到一個區間,在這個區間裏面1和-1加起來要大於0。

第二步:怎樣可以更方便的得到一個區間的和?

在這裏,我們需要利用前綴和這個方法。利用前綴和方法,我們可以將[1,1,-1,-1,-1,-1,1]轉化爲前綴和prefixSrc = [0, 1, 2, 1, 0, -1, -2, -1],我們在前綴和前面加了一個0,是爲了好操作。

如果要得到[1,3]區間的和,根據前綴和的定義,只需要使用prefixSrc[3]-prefixSrc[0]即可。

第三步:我們現在需要找到的是:區間和>0的最長區間。

那麼可以這樣思考,想要prefixSrc[j]大於prefixSrc[i],我們只需要找到比prefixSrc[j]更小的元素在哪裏就可以了。這樣就可以使用單調棧了。

我們先遍歷一遍prefixSrc ,建議一個嚴格單調遞減的單調棧,這樣我們的棧頂元素就一定是prefixSrc 中的最小值。(其中,棧中存儲的是元素的索引)

然後,我們從後向前遍歷prefixSrc ,若遍歷到的元素大於棧頂元素,則這個區間是符合規則的,需要記錄下區間的大小,並且我們將棧頂元素彈出,然後繼續比較當前遍歷到的元素是不是大於棧頂元素。

   

                                              圖一

  

                                        圖二

     

                                          圖三   

  

                                      圖四

                                      圖五

【python代碼】

class Solution:
    def longestWPI(self, hours: List[int]) -> int:
        num = [ 0 for i in range(len(hours))]
        for i in range(len(hours)):
            if hours[i] > 8:
                num[i] = 1
            else:
                num[i] = -1
        j = 0
        ans = []
        ans.append(j)
        for i in num:
            j = j + i
            ans.append(j)
        stack = []
        for i in range(len(num)):
            if len(stack) == 0 or ans[stack[-1]] > ans[i]:
                stack.append(i)
        k = 0
        n = len(hours)
        while n > k:
            while len(stack) != 0 and ans[stack[-1]] < ans[n]:
                k = max(k,n-stack[-1])
                stack.pop()
            n -= 1
        return k

 

 

 

發佈了27 篇原創文章 · 獲贊 2 · 訪問量 1771
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章