同類題目
題目描述
給你乙份工作時間表 hours,上面記錄著某一位員工每天的工作小時數。我們認為當員工一天中的工作小時數大於 8 小時的時候,那麼這一天就是「勞累的一天」。所謂「表現良好的時間段」,意味在這段時間內,「勞累的天數」是嚴格 大於「不勞累的天數」。請你返回「表現良好時間段」的最大長度。
解題思路
題意剖析:題目意思是對於hours 中的每個元素,大於8記為1,否則記為-1,要我們算標記後的陣列中,和大於0的最長區間。
解法1:暴力
兩重for 迴圈,但是無法ac。第一重迴圈用於計算從下標 0,到當前下標 i的字首和第二重迴圈用於計算從下標 0,到當前下標 j 的字首和,兩者字首和的差值若均大於0,則符合條件,此時需要通過判斷對返回值 ret 進行更新。
解法2:雜湊
用乙個 cur 變數記錄字首和,當大於8時,cur++, 小於8時,cur–。由於從前向後遍歷,當 cur > 0時,說明從開始到現在滿足條件,時間必然是最長的,直接更新 res = i + 1。當 cur <= 0時呢?關鍵來了
這裡用乙個 字典記錄所有 cur <= 0的最小下標,所謂最小,就是後面如果再碰到了同樣的 cur,不需要更新,如果沒有碰到過,則把這個下標記錄下來。然後用 cur - 1 去字典裡找,如果找到了下標j,那麼就說明從0到 j 的字首和是 cur-1,而從0到 i 的字首和是 cur,那麼顯然從 j 到 i的和是(cur - (cur - 1)) = 1 > 0,也就是說從 j+1到 i 的表現肯定是滿足的,並且由於 j 是 cur-1中最小的,所以 i-j 是最大的。此時再跟 res 比較看是否需要更新。
上面為什麼只需要查詢 cur-1?因為滿足條件的字首和只能是小於等於cur-1的,也就是說其實也可以查詢 cur-2,cur-3…,但是,cur-2的下標一定不可能在 cur-1的下標左邊。使用反證法,前提是cur-1代表的是最小下標,那麼如果 cur-2在 cur-1左邊,而cur-2的左邊一定還會有 cur-1出現(cur值是從0開始的),這就和最小下標的前提矛盾了。
那麼問題又來了,如果 cur-1不存在,是否要查詢 cur-2,cur-3…呢?也不需要,思路跟上面是一樣的,如果 cur-1不存在,cur-2,cur-3…一定也不存在。舉個例子,不可能從0跳到-2,-3,而中間沒有-1。
通過上面有理有據的分析,下面的**就很簡單了。
解法3:單調棧
其思路和雜湊方法一致,但由於沒有雜湊表的開銷,因此執行速度大大加快。
**
//暴力:超時
class
solution
tmpsum+
=hours[j]
>8?
1:(-
1);}
}return ret;}}
;
//雜湊表
class
solution
}return ret;}}
;
// 單調棧(單調減)
class
solution
for(
int i=sum.
size()
-1;i>=
0;i--)}
return ret;}}
;
LeetCode 1124 表現良好的最長時間段
給你乙份工作時間表 hours,上面記錄著某一位員工每天的工作小時數。我們認為當員工一天中的工作小時數大於 8 小時的時候,那麼這一天就是 勞累的一天 所謂 表現良好的時間段 意味在這段時間內,勞累的天數 是嚴格 大於 不勞累的天數 請你返回 表現良好時間段 的最大長度。示例 1 輸入 hours ...
1124 表現良好的最長時間段
題意 給你乙份工作時間表 hours,上面記錄著某一位員工每天的工作小時數。我們認為當員工一天中的工作小時數大於 8 小時的時候,那麼這一天就是 勞累的一天 所謂 表現良好的時間段 意味在這段時間內,勞累的天數 是嚴格 大於 不勞累的天數 請你返回 表現良好時間段 的最大長度。示例 1 輸入 hou...
1124 表現良好的最長時間段 字首和 雜湊表
難度 中等 題目描述 解題思路 看到這種 要求連續區間而且滿足一定條件,最大 最小等等都可以考慮一下字首和法。字首和最大的醫用就是可以在o 1 時間內得到任意乙個區間 i,j 的和。在這道題裡,當工作時間大於8,設定成1,小於8等於 1,由此計算字首和 如果字首和大於0,說明從0開始的區間裡到當前位...