33-leetCode: 1124. 表现良好的最长时间段

214 阅读1分钟

题目

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

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

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

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

示例

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

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

解题思路

本题可以采用前缀和的思路解题,记大于8小时为1,小于8小时为-1,那么,将前缀和记录为count,大于8小时 count+1,小于8小时-1,结果长度初始化为0。定义一个map,用来记录前缀和<=0时的下标。当count > 0 时,结果+1;当count小于等于0 时,记录下count<=0 的下标,如果当前count-1有被记录过, 那么结果就取当前结果值和当前下标到count-1的mapzhi值(区间)的最大值,最后,result就是最长的有效工作时长

/**
 * @param {number[]} hours
 * @return {number}
 */
var longestWPI = function(hours) {
        let count = 0; // 大于8h的累计天数
        let result = 0; // 有效工作时长的长度
        let map = new Map(); // 存放count <= 0的下标
        for (let i = 0; i < hours.length; i++) {
            // 记录前缀和
            if (hours[i] > 8) {
                count++;
            } else {
                count--;
            }
            // 累计天数大于0 有效天数+1;
            if (count > 0) {
                result = i + 1;
            } else {
                if (!map.has(count)) {
                    map.set(count, i); // 记录第一次count<=0的下标, count可能 = 0, -1, -2, -3
                }
                if (map.has(count - 1)) { // 如果有count的前一次记录,此时count-1到count符合要求
                    result = Math.max(result, i - map.get(count - 1));
                }
            }
        }
        // 最后返回有效长度
        return result;
};