我参与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
}
结束语
如果您喜欢我的文章,可以[关注⭐]+[点赞👍]+[评论📃],您的三连是我前进的动力,期待与您共同成长~