[路飞]_leetcode_1124. 表现良好的最长时间段

300 阅读1分钟

给你一份工作时间表 hours,上面记录着某一位员工每天的工作小时数。

我们认为当员工一天中的工作小时数大于 8 小时的时候,那么这一天就是「劳累的一天」。

所谓「表现良好的时间段」,意味在这段时间内,「劳累的天数」是严格 大于「不劳累的天数」。

请你返回「表现良好时间段」的最大长度。

解题思路

可以将工作时间数转变为 劳累天数 +1,不劳累天数 -1

然后利用前缀和计算所有工作时间区间的累加和

例如: [9, 9, 6, 0, 6, 6, 9] 转变为: [1, 1,-1,-1,-1,-1, 1] 前缀和: [0, 1, 2, 1, 0,-1,-2,-1]

根据题目我们求的是「表现良好时间段」的最大长度,而累加和可以求区间的和 这就意味着求时间区间和大于0的时间段就是「表现良好时间段」

代码

var longestWPI = function(hours) {
    // 计算前缀和
    let preSum = new Array(hours.length + 1).fill(0);
    for (let i = 0; i < hours.length; i++) {
        if (hours[i] > 8) preSum[i + 1] = preSum[i] + 1;
        else preSum[i + 1] = preSum[i] - 1
    }
    // 记录最小的前缀和下标
    let stack = [0];
    for (let i = 0; i < preSum.length; i++) {
        if (preSum[i] < preSum[stack[stack.length - 1]]) stack.push(i)
    }
    console.log(stack)
    console.log(preSum)
    // 求最大值
    let max = 0
    // 0, 1, 2, 1, 0, -1, -2, -1
    for (let i = preSum.length - 1; i > max; i--) {
        while (stack.length && preSum[stack[stack.length-1]] < preSum[i]) {
            max = Math.max(max, i - stack.pop())
        }
    }
    return max
};