[路飞]-leetcode1124 表现良好的时间段

316 阅读1分钟

我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战

1124. 表现良好的最长时间段

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

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

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

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

解法一:暴力解法
// 1. 首先将数组里的元素转换成我们好处理的
// hours: [9,9,6,0,6,6,9]
var longestWPI = function(hours){
    var ht = new Array(hours.length  + 1).fill(0)
    for(let i= 0; i< hours.length; i++){
        if(hours[i] > 8) ht[i+1] = ht[i] + 1
        else ht[i+1] = ht[i] -1  
    }
    // ht: [0,1,2,1,0,-1,-2,-1]
    
    // 两层循环
    let max = 0
    for(let i = 0; i< ht.length-1;i++){
        for(let j = i+1; j <= ht.length;j++){
            if(ht[i] < ht[j]){
                max = Math.max(max, j - i) // 逐一向前比对,找出最长
            }
        }
    }
    return max;
}
解法二: 单调栈

首先求出前缀和,根据前缀和得出单调递减栈,然后又后遍历如果当前索引位的值 大于 栈,则一直弹出直到不大于为止。 更新最大宽度。

// hours: [9,9,6,0,6,6,9]
var longestWPI = function(hours){
    // 求前缀和
    var ht = new Array(hours.length + 1).fill(0)
    for(let i= 0; i< hours.length; i++){
        if(hours[i] > 8){
            ht[i + 1] = ht[i] +1
        }else{
            ht[i + 1] = ht[i] -1
        }
    }
    // ht: [0,1,2,1,0,-1,-2,-1]
    let stack = [] // 单调栈
    stack.push(0)
    for(let i =1; i< ht.length;i++){
        if(ht[stack[stack.length - 1]] > ht[i]) stack.push(i) // 栈存的是索引,严格单调递减
    }
    // stack: [0,5,6]  
    let max = 0
    for(i = ht.length -1; i>max ; i--){ 
        while(stack.length > 0 && ht[stack[stack.length-1]] < ht[i]){
            max = Math.max(max, i - stack.pop())  // 从右到左计算,与栈顶索引指向元素比较,如果相减结果大于 0,则一直出栈,直到不大于 0 为止,然后更新当前最大宽度
        }
    }
    return max
   
}

结束语

如果您喜欢我的文章,可以[关注⭐]+[点赞👍]+[评论📃],您的三连是我前进的动力,期待与您共同成长~