【LeetCode】1124. 表现良好的最长时间段

news2024/11/26 3:51:49

1124. 表现良好的最长时间段

题目描述

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

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

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

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


示例 1

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


示例 2

输入:hours = [6,6,6]
输出:0


提示

  • 1 <= hours.length <= 104
  • 0 <= hours[i] <= 16

算法一:前缀和 + 单调栈

思路

  1. 观察到题目中给出数组中的元素有且只有两种, 分别是大于 8小于等于 8 ,简单起见, 可以用 1 代表大于 8 的元素, 用 -1 代表小于等于 8 的元素,例 1 的数组表示为:[1, 1, -1, -1, -1, -1, 1],记为 arr。

  2. 现在题目转换成, 需要找到一个子列, 其中 1 的元素数量严格大于 -1 的元素数量。

  3. 继续简化 : 需要找到一个子列, 其中所有元素的和大于 0

  4. 这时很容易想到直接暴力遍历所有子列, 找到和大于 0 且长度最大的子列即可。

    • 我们需要的仅仅是 子列和 ,所以可以借助前缀和求解, 计算数组 arr 的前缀和, 得到数组 prefixSum = [0, 1, 2, 1, 0, -1, -2, -1], 关于前缀和的知识可以见参考资料。
  5. 将任意一个子列表示为(i, j), i 和 j 分别是 prefixSum 数组中的某个元素的下标;

  6. 直接遍历每一个(i,j)即可找出答案;

  7. 继续优化, 明确我们的目标:「 找到一个(i, j) 使得 prefixSum[j] - prefixSum[i] > 0 」。

    • 在遍历 j 的过程中, 给定任意 i < j1 < j2 ,如果prefixSum[i] < prefixSum[j2] ,那么(i, j1) 一定不是答案, 也就是说, 如果 (i, j2) 符合条件, 那么它们中间的所有 j1 都不需要检查,因此我们可以从右往左遍历 j
    • 在遍历外层循环 i 的过程中, 对于任意的 i < i1 < j , 如果 prefixSum[i1] >= prefixSum[i], 那么(i1, j) 一定不会是答案,因为:
      • 如果 prefixSum[i1] < prefixSum[j] ,由于(i, j)更长,所以i1, j) 不会是答案;
      • 如果 prefixSum[i1] > prefixSum[j] ,由于我们找的是 prefixSum[j] - prefixSum[i1] > 0 的(i, j),所以这种情况也不会是答案。
  8. 这时我们需要从头遍历一遍 prefixSum , 找到一个严格单调递减的数组,比如测试用例,只有[0, -1, -2]符合要求, 它们对应的下标是stk = [0, 5, 6], 这可能是 i 的候选项, 由于最终答案需要的是最长距离, 所以需要存储下标。

  9. 现在问题转换成, 遍历 stk = [0, 5, 6] ,拿到一个 i ,再从右往左遍历 prefixSum ,拿到一个 j 检查每一对 (i, j)。

  10. 此时再观察:

    • 对于一个 j ,如果它满足 prefixSum[j] > prefixSum[stk[0]] ,那么 (0, j)是候选项, 但是由于 stk 是单调递减的, 所以 prefixSum[j] 也大于其余的 prefixSum[stk[0+x]] ,因此 stk 全体都是 i 的候选项, 即 (stk[x] , j)都是候选项;
    • 对于一个 j ,如果它满足 prefixSum[j] < prefixSum[stk[0]] ,那么(0, j)不是候选项,至于其他的 stk 还需要另外判断;
    • 但是如果反过来, 反向遍历 stk , 对于一个 j , 如果它满足 prefixSum[j] < prefixSum[stk[-1]] ,因为是单调递减的, 所有 stk 的其他元素肯定也大于 prefixSum[j] ,可以直接排除 j ;
    • 然后, 如果对于一个 j , 如果它满足 prefixSum[j] > prefixSum[stk[-1]] , 那么 (stk[-1], j) 就是候选项,此时, j 继续向左遍历没有意义, 因此可以排除 stk[-1] ,遍历 stk[-2] 及剩下的元素。
  11. 根据上述思路, 操作恰好契合, 所以用栈 stk 存储可能的 i 。

收获

  • 一开始想用 滑动窗口 做, 但是这道题不存在单调性,而使用双指针维护的时候,如果快指针走到不满足条件的位置后,慢指针并不知道该往左还是往右。
  • 通过这道题学习了单调栈前缀和 ,前缀和之前有出现过,但是一直没学会。
  • 这道题的思路值得回顾,一步步得到最终结果。

算法情况

  • 时间复杂度:O(n),由于元素出栈入栈最多一次,所以二重循环的时间复杂度最多为O(n);
  • 空间复杂度:O(n)。
    在这里插入图片描述

代码

class Solution {
public:
    int longestWPI(vector<int>& hours) {
        int ans = 0, n = hours.size();
        vector<int> arr(n);
        vector<int> prefixSum(n+1);
        stack<int> stk;
        stk.push(0);
        prefixSum[0] = 0;
        for(int i=1; i<n+1; i++){
            arr[i-1] = hours[i-1] > 8 ? 1 : -1; 
            prefixSum[i] = arr[i-1] + prefixSum[i-1]; // 前缀和
            cout<<prefixSum[i]<<endl;
            if(prefixSum[i] < prefixSum[stk.top()])    stk.push(i);
        }
        // for(auto & t : prefixSum)   cout<<t<<" ";
        for(int j=n; j>0; --j){
            while(!stk.empty() && prefixSum[j] > prefixSum[stk.top()]){
                cout<<stk.top()<<endl;
                ans = max(ans, j - stk.top());
                stk.pop();
            }
        }
        return ans;
    }
};

参考资料:

  1. 优秀题解,两种解法
  2. 单调栈和应用实践
  3. 前缀和
  4. 【重要】题解2,有详细思路,比较容易看懂

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/345853.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多线程下载工具axel的安装和使用

多线程下载工具axel的安装和使用 Axel是一个轻量级下载程序&#xff0c;它和其他加速器一样&#xff0c;对同一个文件建立多个连接&#xff0c;每个连接下载单独的文件片段以更快地完成下载。 Axel 支持 HTTP、HTTPS、FTP 和 FTPS 协议。它也可以使用多个镜像站点下载单个文件…

Springboot 使用插件 自动生成Mock单元测试 Squaretest

缘起 很多公司对分支单测覆盖率会有一定的要求&#xff0c;比如 单测覆盖率要达到 60% 或者 80%才可以发布。 有时候工期相对紧张&#xff0c;就优先开发功能&#xff0c;测试功能&#xff0c;然后再去补单元测试。 但是编写单元测试又比较浪费时间&#xff0c;有没有能够很大…

Spirng 痛苦源码学习(四)——AOP老大哥

文章目录前言一、探究AOP开始&#xff0c;判断导入的相关组件1.跟踪源码流程二、对切面中的增强方法进行增强1.源码的过程三、使用aop的目标类生成代理对象总结前言 Spring的两大特性&#xff1a;IOC&#xff1b;AOP。本篇仅以跟完Spring AOP相关源码为依据写的总结 一、探究A…

MySQL入门篇-MySQL高级窗口函数简介

备注:测试数据库版本为MySQL 8.0 这个blog我们来聊聊MySQL高级窗口函数 窗口函数在复杂查询以及数据仓库中应用得比较频繁 与sql打交道比较多的技术人员都需要掌握 如需要scott用户下建表及录入数据语句&#xff0c;可参考:scott建表及录入数据sql脚本 分析函数有3个基本组成…

matlab进行双目标定获取双目参数并打印教程

文章目录前言1.打开matlab进行双目标定2.获取想要的参数前言 在相同的标定算法和标定参数下&#xff0c;Python和Matlab的标定精度是相同的。因为标定精度主要取决于标定算法和标定参数的质量&#xff0c;而不是编程语言的选择。 不同的编程语言可能使用不同的库或实现细节&…

Hackergame 2020

3.Hackergame 2020 1.签到 url&#xff1a;http://202.38.93.111:10000/ 打开签到题页面&#xff0c;拖动滑杆&#xff0c;如果将滑杆滑动到最左边&#xff0c;提交 0&#xff0c;那么我们会得到成功的返回&#xff0c;但是没有 flag 尝试手动提交一些非整数的值&#xff0c…

HTML+CSS

HTML技术 什么是HTML Hyper Text Markup Language HTML&#xff1a;超文本标记语言&#xff0c;内部全部是一些不同的标记符号。 通俗的来讲&#xff1a;其实就是“网页”。 HTML 网页 网页的特点&#xff1a; 1、所有的网页都是通过【浏览器】来进行解析的。2、所有的网…

【MySQL】子查询

这里写自定义目录标题子查询1、子查询的基本使用2、 单行子查询2.1、单行比较查询2.2、HAVING 中的子查询2.3、CASE中的子查询3、多行子查询4、相关子查询5、EXISTS 与 NOT EXISTS关键字子查询 子查询指一个查询语句嵌套在另一个查询语句内部的查询&#xff0c;这个特性从MySQ…

算法笔记(四)—— 排序算法总结及链表

排序算法稳定性 值相同的元素排序结束后能否保持相对秩序不变。 冒泡排序具有稳定性&#xff08;相等时不交换&#xff09;。 插入排序具有稳定性。 归并排序具有稳定性&#xff08;merge的时候&#xff0c;相等时先拷贝左边的&#xff0c;小和问题让其丧失了稳定性&#x…

557. 反转字符串中的单词 III

给定一个字符串 s &#xff0c;你需要反转字符串中每个单词的字符顺序&#xff0c;同时仍保留空格和单词的初始顺序。 方法一&#xff1a;使用额外空间 思路与算法 开辟一个新字符串。然后从头到尾遍历原字符串&#xff0c;直到找到空格为止&#xff0c;此时找到了一个单词&a…

Http中你必须知道那点事

1, HTTP 1.1 简介 HTTP概念 HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff0c;规定了浏览器和服务器之间数据传输的规则。 数据传输的规则指的是请求数据和响应数据需要按照指定的格式进行传输。如果想知道具体的格式&#xff0c;可以打开浏览器&#xf…

2、线程、块和网格

目录一、线程、块、网格概念二、代码分析2.1 打印第一个线程块的第一线程2.2 打印当前线程块的当前线程2.3 获取当前是第几个线程一、线程、块、网格概念 CUDA的软件架构由网格&#xff08;Grid&#xff09;、线程块&#xff08;Block&#xff09;和线程&#xff08;Thread&am…

Allegro如何设置导入Subdrawing可自由选择目录操作指导

Allegro如何设置导入Subdrawing可自由选择目录操作指导 用Allgro做PCB设计的时候,导入Subdrawing是非常常用的功能,在导入Subdrawing的时候,通常需要把Subdrawing文件放在需要导入PCB的相同目录下,不能自由选择,如下图 但是Allegro是支持自由选择目录的,只需按照下方的步…

Sphinx文档生成工具(一)

Sphinx在项目中部署应用 一、将安装的Sphinx发布 创建FindSphinx.cmake&#xff0c;这个名字只能是这个 find_program(SPHINX_EXECUTABLE NAMES sphinx-buildHINTS$ENV{SPHINX_DIR}HINTS ${SPHINX_ROOT}/binPATH_SUFFIXES binDOC "Sphinx documentation generator"…

企业为什么需要绩效管理软件?

随着经济的发展&#xff0c;企业的竞争日益激烈&#xff0c;“纸上谈兵”的绩效考核机制已经远远不能满足企业管理的需要。因此&#xff0c;企业绩效管理软件的重要性也日益凸显。 绩效管理软件可以提高企业管理效率、提高HR工作效率、提高员工工作能力。 今天就来给大家详细…

【C++】从0到1入门C++编程学习笔记 - 实战篇:演讲比赛流程管理系统

文章目录一、演讲比赛程序需求1.1 比赛规则1.2 程序功能1.3 程序效果图&#xff1a;二、项目创建2.1 创建项目2.2 添加文件三、创建管理类3.1创建文件3.2 头文件实现3.3 源文件实现四、菜单功能4.1 添加成员函数4.2 菜单功能实现4.3 测试菜单功能五、退出功能5.1 提供功能接口5…

RiproV2主题右侧美化右侧导航美化RiproV2主题右侧个人中心美化保持常驻

背景: RiproV2主题右侧美化右侧导航美化RiproV2主题右侧个人中心美化保持常驻 原样式没有文字只有图标,修改之后有文字,并且保持常驻在右侧,不随页面滚动而滚动 下面是楼主网站优化后的效果:

Linux中定时监控Tomcat服务器进程并在进程结束时重启Tomcat服务器

目录一、问题二、解决方法1、创建定时任务文件2、修改Tomcat的部分文件3、添加系统的定时调度4、执行monitor.sh文件5、查看脚本执行的日志文件一、问题 当我们的Tomcat配置完成后投入使用后&#xff0c;在用户使用一定时间后&#xff0c;Tomcat可能会出现一些问题导致进程结束…

mybatis-plus ---2

mybatis-plus插件 官网地址 分页插件 MyBatis Plus自带分页插件&#xff0c;只要简单的配置即可实现分页功能 配置并使用自带分页插件 Configuration MapperScan("com.itzhh.mapper")//可以将主类中的注解移到此处 public class MybatisPlusConfig {Beanpublic …

MySQL数据库调优————OPTIMIZER_TRACE详解

OPTIMIZER_TRACE是MySQL5.6引入的一项跟踪功能&#xff0c;它可以跟踪优化器做出的各种决策&#xff08;比如访问表的方法、各种开销计算、各种转换等&#xff09;&#xff0c;并将跟踪结果记录到INFORMATION_SCHEMA.OPTIMIZER_TRACE表中。此功能默认关闭&#xff0c;开启后 &a…