给你一份工作时间表 hours
,上面记录着某一位员工每天的工作小时数。
我们认为当员工一天中的工作小时数大于 8
小时的时候,那么这一天就是「劳累的一天」。
所谓「表现良好的时间段」,意味在这段时间内,「劳累的天数」是严格 大于「不劳累的天数」。
请你返回「表现良好时间段」的最大长度。
示例 1:
输入:hours = [9,9,6,0,6,6,9] 输出:3 解释:最长的表现良好时间段是 [9,9,6]。
示例 2:
输入:hours = [6,6,6] 输出:0
提示:
1 <= hours.length <= 10^4
0 <= hours[i] <= 16
提示 1
Make a new array A of +1/-1s corresponding to if hours[i] is > 8 or not. The goal is to find the longest subarray with positive sum.
提示 2
Using prefix sums (PrefixSum[i+1] = A[0] + A[1] + ... + A[i]), you need to find for each j, the smallest i < j with PrefixSum[i] + 1 == PrefixSum[j].
解法:前缀和 + 哈希表
我们记工作小时数大于 8 的为 1 分,小于等于 8 的为 −1 分,原问题由求解最长的「表现良好的时间段」长度转变为求解分数和大于 0 的最长区间长度。
我们使用前缀和 s,对于某个下标 i(从 0 开始),我们期待找到最小的 j (j<i),满足 s[j]<s[i]。接下来,我们按照 s[i] 是否大于 0 来分情况讨论:
- 如果 s[i]>0,那么前 i+1 项元素之和大于 0,表示有一个长度为 i+1 的大于 0 的区间。
- 如果 s[i]<0,我们在前面试图寻找一个下标 j,满足 s[j]=s[i]−1。如果有,则表示区间 [j+1,i] 是我们要找的以 i 结尾的最长区间。
为什么第 2 种情况要找 s[i]−1,而不是 s[i]−2 或更小的一项?因为在本题中分数只有 1 或者 −1,如果前缀和数组中在 i 之前要出现小于 s[i] 的元素,它的值一定是 s[i]−1。也就是说当 s[i]<0 时,我们要找到 j 使得 s[j]<s[i],如果有这样的 j 存在,这个 j 一定满足 s[j]=s[i]−1。
实现过程中,我们可以使用哈希表记录每一个前缀和第一次出现的位置,即可在 O(1) 的时间内判断前缀和等于 s[i]−1 的位置 j 是否存在。
类似题型:LeetCode 面试题 17.05. 字母与数字-CSDN博客
LeetCode 1546. 和为目标值且不重叠的非空子数组的最大数目-CSDN博客
Java版:
class Solution {
public int longestWPI(int[] hours) {
int maxLength = 0;
int presum = 0;
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < hours.length; i++) {
presum += hours[i] > 8 ? 1 : -1;
if (presum > 0) {
maxLength = i + 1;
} else {
if (map.containsKey(presum - 1)) {
maxLength = Math.max(maxLength, i - map.get(presum - 1));
}
}
if (!map.containsKey(presum)) {
map.put(presum, i);
}
}
return maxLength;
}
}
Python3版:
class Solution:
def longestWPI(self, hours: List[int]) -> int:
maxLength = 0
dic = dict()
presum = 0
for i, hour in enumerate(hours):
presum += 1 if hour > 8 else -1
if presum > 0:
maxLength = i + 1
else:
if presum - 1 in dic:
maxLength = max(maxLength, i - dic[presum - 1])
if presum not in dic:
dic[presum] = i
return maxLength
复杂度分析
-
时间复杂度:O(n),其中 n 为 hours 的长度。
-
空间复杂度:O(n),其中 n 为 hours 的长度。