表现良好的最长时间段及自我反省

一、表现良好的最长时间段

1.题目介绍

给你一份工作时间表 hours,上面记录着某一位员工每天的工作小时数。

我们认为当员工一天中的工作小时数大于 8 小时的时候,那么这一天就是「劳累的一天」。

所谓「表现良好的时间段」,意味在这段时间内,「劳累的天数」是严格 大于「不劳累的天数」。

请你返回「表现良好时间段」的最大长度。

示例 1:

输入:hours = [9,9,6,0,6,6,9]
输出:3
解释:最长的表现良好时间段是 [9,9,6]。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-well-performing-interval

2.我的思路及错误的代码

刚开始看的时候一脸懵逼,于是看了提示。
在这里插入图片描述
第一个提示比较好完成,我遍历了一遍列表然后就完成了第一个提示。然后第二个提升我就有点迷,用了一个嵌套循环来判断,于是时间复杂度直接变成o(n2),代码如下。

for i in range(k-1):
    for j in range(i+1,k):
        if persum[i] + 1 == persum[j]:
            s.append(j-i)

我的思路大概是先按照提示一写一个栈stack,然后写一个persum保存前缀和,接下来计算stack里面1和-1的个数,如果1的个数>-1的个数直接返回hours的长度,否则利用提示二判断,结果就出现了如下错误。
在这里插入图片描述
于是我就安心去看大佬们的代码了。
我的错误代码如下:(仅供大家愉悦身心,笑一会就行了,别一直笑啊!)

class Solution:
    def longestWPI(self, hours: List[int]) -> int:
        if not hours:return 0
        stack = []
        for i in hours:
            if i > 8:
                stack.append(1)
            else:
                stack.append(-1)
        sum2 = 0
        persum = []
        for i in stack:
            persum.append(sum2)
            sum2 += i
        k =len(stack)
        s = []
        m1 = stack.count(1)
        m2 = stack.count(-1)
        if m1 > m2:
            return k
        else:
            for i in range(k-1):
                for j in range(i+1,k):
                    if persum[i] + 1 == persum[j]:
                        s.append(j-i)
        if s != []:
            m = max(s)
            return m
        else:
            return 0

3.大佬的思路

一个比较受欢迎的思路是用单调栈(栈里面存储的数据是有序的),大佬说962最大宽度坡和这个题目的变形类似,不过我更想谈谈另外一个可能比较小众的哈希法,这个大佬的哈希法惊艳到我了。代码如下。

class Solution:
    def longestWPI(self, hours: List[int]) -> int:
        if len(hours)==0:return 0
        idx = {0:0}
        maxlen,min_flag,sum_flag=0,0,0
        for i in range(1,len(hours)+1):
            sum_flag=sum_flag+(1 if hours[i-1]>8 else -1)
            if sum_flag < min_flag:
                idx[sum_flag]=i
                min_flag = sum_flag
            if sum_flag-1 in idx:
                maxlen = max(maxlen,i-idx[sum_flag-1])
        if sum_flag>0:maxlen=len(hours)
        return maxlen
作者:skay2002
链接:https://leetcode-cn.com/problems/longest-well-performing-interval/solution/bu-xu-yao-dan-diao-zhan-zhi-jie-qian-zhui-he-ha-xi/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

大佬说画一条前缀和的变化曲线,然后很快就可以获得思路了,我尝试脑补了一下,发现好像是这么回事,如下图。(图丑字丑,请见谅。)
在这里插入图片描述
因为只将min_flag之前的数值放入哈希表,所以进行比较,可以得到最长的时间段。

总结

1.单调栈的概念和运用。概念是栈存储的数据是按照顺序排列;运用是先得到一个单调栈,然后逆序遍历,求得最大的时间段。
2.题目和数学相结合,可以帮助得到思路。
3.前缀和的求解。presum[i] = presum[i - 1] + score[i - 1]
最后希望以后ac的代码不是别人的…
在这里插入图片描述

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页