leecode算法1-1124 表现良好的最长时间段(JAVA)

1、题目

给你一份工作时间表 hours,上面记录着某一位员工每天的工作小时数。
我们认为当员工一天中的工作小时数大于 8 小时的时候,那么这一天就是「劳累的一天」。
所谓「表现良好的时间段」,意味在这段时间内,「劳累的天数」是严格 大于「不劳累的天数」。
请你返回「表现良好时间段」的最大长度。
示例 1:
输入:hours = [9,9,6,0,6,6,9]
输出:3
解释:最长的表现良好时间段是 [9,9,6]。
提示:
1 <= hours.length <= 10000
0 <= hours[i] <= 16

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-well-performing-interval
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2、错误算法

class Solution {
    public int longestWPI(int[] hours) {
        int tired = 0;
            int nottired = 0;
            int goodPerformance = 0;
            int preGoodPerformance = 0;
        for(int i = 0;i<hours.length;i++){
            
            if(hours[i]>8){
                tired++;
            }else {
                nottired++;
            }
            if(nottired >= tired){
                tired = 0;
                nottired = 0;
                if(goodPerformance>preGoodPerformance){
                    preGoodPerformance = goodPerformance;
                }
                goodPerformance = 0;
            }
            goodPerformance++;
        }
        return preGoodPerformance;
    }
}

3、暴力破解算法(网上大神提供)

算法讲解
用一个 cur 变量记录前缀和,当大于8时,cur++, 小于8时,cur–。由于从前向后遍历,当 cur > 0时,说明从开始到现在满足条件,时间必然是最长的,直接更新 res = i + 1。当 cur <= 0时呢?关键来了这里用一个 字典记录所有 cur <= 0的最小下标,所谓最小,就是后面如果再碰到了同样的 cur,不需要更新,如果没有碰到过,则把这个下标记录下来。然后用 cur - 1 去字典里找,如果找到了下标j,那么就说明从0到 j 的前缀和是 cur-1,而从0到 i 的前缀和是 cur,那么显然从 j 到 i的和是(cur - (cur - 1)) = 1 > 0,也就是说从 j+1到 i 的表现肯定是满足的,并且由于 j 是 cur-1中最小的,所以 i-j 是最大的。
此时再跟 res 比较看是否需要更新。
上面为什么只需要查找 cur-1?因为满足条件的前缀和只能是小于等于cur-1的,也就是说其实也可以查找 cur-2,cur-3…,但是,cur-2的下标一定不可能在 cur-1的下标左边。使用反证法,前提是cur-1代表的是最小下标,那么如果 cur-2在 cur-1左边,而cur-2的左边一定还会有 cur-1出现(cur值是从0开始的),这就和最小下标的前提矛盾了。
那么问题又来了,如果 cur-1不存在,是否要查找 cur-2,cur-3…呢?
也不需要,思路跟上面是一样的,如果 cur-1不存在,cur-2,cur-3…一定也不存在。举个例子,不可能从0跳到-2,-3,而中间没有-1。
通过上面有理有据的分析,下面的代码就很简单了。

代码

class Solution {
    public int longestWPI(int[] hours) {
        int cur = 0;
        int res = 0;
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < hours.length; i++) {
            if (hours[i] > 8) {
                cur++;
            } else {
                cur--;
            }
            if (cur > 0) {
                res = i + 1;
            } else {
                if (!map.containsKey(cur)) {
                    map.put(cur, i);
                }
                if (map.containsKey(cur - 1)) {
                    res = Math.max(res, i - map.get(cur - 1));
                }
            }
        }
        return res;
    }
}

作者:li-zi-he
链接:https://leetcode-cn.com/problems/longest-well-performing-interval/solution/bie-gen-lao-fu-ti-shi-yao-dan-diao-zhan-by-li-zi-h/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值