1. 题目与解析
给你一份工作时间表 hours,上面记录着某一位员工每天的工作小时数。
我们认为当员工一天中的工作小时数大于 8 小时的时候,那么这一天就是「劳累的一天」。
所谓「表现良好的时间段」,意味在这段时间内,「劳累的天数」是严格 大于「不劳累的天数」。
请你返回「表现良好时间段」的最大长度。
输入: hours = [9,9,6,0,6,6,9]
输出: 3
解释: 最长的表现良好时间段是 [9,9,6]。
输入: hours = [6,6,6]
输出: 0
本体的最终目的是计算最大的劳累的一天比摸鱼的一天总数上更多的子数组长度。
根据题意,可以考虑使用动态规划的思路解题,不过需要注意的是,如果是使用n*n大小的dp数据规模,会造成内存空间不足,因此需要优化成n的空间规模。
首先,我们可以计算从从0到i位的所有位数中是劳累的一天的总数并且进行记录,记录如果为正数,那么说明这一定范围内劳累的一天比摸鱼的一天总数多,如果记录为负数,那么说明这一定范围内劳累的一天比摸鱼的一天总数少。
有了上面的基础记录,就可以计算出任意的i位到j位的范围中,劳累的一天比摸鱼的一天多的天数,在这个计算的过程中,可以同步更新统计的longestWPI,最后输出结果即可。
需要注意的一点是,在计算过程中,要注意dp的初始化。
2. 题解
class Solution {
public int longestWPI(int[] hours) {
int longestWPI = 0, n = hours.length;
if (n == 0) {return 0;}
int[] dp = new int[n];
dp[0] = hours[0] > 8? 1: -1;
longestWPI = hours[0] > 8? 1: 0;
for (int i = 1; i < n; i++) {
dp[i] = dp[i-1] + (hours[i] > 8? 1: -1);
if (dp[i] > 0) {
longestWPI = i + 1;
}
}
for (int i = 1; i < n; i++) {
for (int j = i; j < n; j++) {
boolean isNice = dp[j] - dp[i-1] > 0? true: false;
if (isNice && j - i + 1 > longestWPI) {
longestWPI = j - i + 1;
}
}
}
return longestWPI;
}
}