【路飞】算法与数据结构-表现良好的最长时间段

595 阅读1分钟

LeetCode:地址

题目要求

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

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

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

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

示例 1:

输入: hours = [9,9,6,0,6,6,9]
输出: 3
解释: 最长的表现良好时间段是 [9,9,6]

示例 2:

输入: hours = [6,6,6]
输出: 0

提示:

  • 1 <= hours.length <= 104
  • 0 <= hours[i] <= 16
思路

单调栈:

维护一个表现不良好的时间段,意义在于栈相邻的两个时间点,都是表现不良好的时间段; 设置基点0,用于判定第一个下坡路段; 需要获取的是前缀和的上坡路段,所以维护一个单调递减栈; 前缀和需要从后面开始遍历。

代码
/**
 * @param {number[]} hours
 * @return {number}
 */
var longestWPI = function (hours) {
    let len = hours.length;
    let change = new Array();
    hours.forEach(val => {
        change.push(val > 8 ? 1 : -1);
    });
    let preSum = new Array();
    preSum[0] = 0;
    change.forEach((val, ind) => {
        preSum.push(val + preSum[ind]);
    })
    let stack = [];
    stack.push(0);
    preSum.forEach((val, ind) => {
        if (preSum[stack[stack.length - 1]] > val) {
            stack.push(ind);
        }
    })
    let result = 0;
    for (let i = len; i >= 0; i--) {
        while (stack.length > 0 && preSum[i] > preSum[stack[stack.length - 1]]) {
            result = Math.max(result, i - stack.pop());
        }
    }
    return result;
};