来自北大算法课的Leetcode题解:1124. 表现良好的最长时间段

代码仓库Github | Leetcode solutions @doubleZ0108 from Peking University.

  • 解法1(T53% S51%):题目看起来简单,但想起来还是很难的,最后还是看了很多题解才大致明白。因为工作时间只有两种可能,因此转为二值数组会简单一点,将>8的转为+1,<8的变为-1,然后求取前缀和,那问题就转化为找到距离最远的i和j,使得s[j]-s[i]为正,二者的这个减法就相当于i~j区间内的求和,如果求和>0则代表着这个区间段内工作>8小时的天数更多,但也要分两种情况
    • 如果第i位的前缀和>0,则代表从0到i一定能构成表现良好的区间,而且随着i的循环,i肯定是在变大的,直接更新就好,这个比较好理解(相当于>8的天一定比<8的多,才可能让前缀和为正)
    • 但如果第i位的前缀和<0,那就意味着从0开始算的话<8的天数更多,所以左边边界肯定要往后,那具体要往后多少呢?因为我们已经将原数组转换为只有+1和-1的数组,因此如果当前位的前缀和为-x的情况下,一定在此之前存在-x-1这个数,因为每次我们都只能+1或者-1,而我能从-x-1变到现在第i位的-x,那一定证明这个区间段里有更多的工作>8小时的天。因此具体实现的时候我把每一个<0的前缀和下标都保存到哈希表中,当发现一个位置的前缀和位-x,我就找-x-1在不在哈希表中,如果在那二者的下标差就是结果,注意不要更新已经存在于哈希表中的key-val,因为本题是要求最大的长度
class Solution:
    def longestWPI(self, hours: List[int]) -> int:
        hours = [1 if x>8 else -1 for x in hours]
        for i in range(1, len(hours)):
            hours[i] += hours[i-1]

        res = 0
        table = {}
        for i in range(len(hours)):
            if hours[i] > 0:
                res = i+1 # 如果某个位置 前缀和>0 则代表从头到这里就构成了一个良好时间段
            else:
                if hours[i] not in table:
                    table[hours[i]] = i
                if hours[i]-1 in table:
                    res = max(res, i-table[hours[i]-1])

        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

doubleZ0108

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值