1124. 表现良好的最长时间段
难度:中等
题目描述
解题思路
看到这种 要求连续区间 而且满足一定条件,最大/最小等等都可以考虑一下前缀和法。前缀和最大的医用就是可以在O(1)时间内得到任意一个区间(i,j)的和。
在这道题里,当工作时间大于8,设置成1,小于8等于-1,由此计算前缀和
如果前缀和大于0,说明从0开始的区间里到当前位置都满足要求,长度等于i;
重点在于小于0的情况,因为题目要求严格大于,如果当前位置小于0,例如等于-2,要想在区间里满足要求,那么区间另一个端点至少要是-3,这时区间长度是最长的。去哈希表里找找有没有前缀和是-3的点,在-3到-2这段里是满足要求的
public static int longestWPI(int[] hours) {
int re = 0,n = hours.length;
HashMap<Integer, Integer> hashMap = new HashMap<Integer, Integer>(); //记录前缀和出现的最小下标
int[] day = new int[n+1];
day[0] = 0;
for (int i = 0; i < n; i++) { //计算前缀和
if(hours[i] > 8) {
day[i+1] = day[i] + 1;
}else {
day[i+1] = day[i] - 1;
}
if(day[i+1] > 0)
re = i+1;
else {
if(!hashMap.containsKey(day[i+1]))
hashMap.put(day[i+1], i+1); //哈希表里面只存放小于0的前缀下标
}
}
for (int i = 1; i < n+1; i++) {
if(day[i] <= 0 && hashMap.containsKey(day[i] - 1)) {
re = Math.max(re, i-hashMap.get(day[i]-1));
}
}
return re;
}