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

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

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

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

输入:hours = [9,9,6,0,6,6,9]。

输出:3。

答案2023-06-16:

大体步骤如下:

1.首先,定义函数 func longestWPI1(hours []int) intfunc longestWPI2(hours []int) int,参数分别为一个 int 型切片 hours,返回值为 int 类型。

2.在 func longestWPI1(hours []int) int 中,声明一个 map 类型的变量 m,用于保存前缀和 sum 出现的最早位置。新建 map 时,将 0 值和 -1 下标添加到 m 中,表示前缀和为 0 的位置为 -1。

3.在 func longestWPI2(hours []int) int 中,声明一个长度为 2n+1 的切片 early,用于保存前缀和 sum 第一次出现的位置。新建 early 时,将所有下标初始化为 -2,表示都未被访问过。将 -1 的值保存至 early[n],表示前缀和为 0 的位置为 -1。

4.在双函数中,都使用变量 ans 和 sum 进行计算,ans 表示最大的表现良好时间段的长度,sum 表示前缀和。

5.遍历 hours,对于每个元素 hour,若 hour>8,则 sum 加一;否则,sum 减一。

6.如果 sum 大于 0,则表明从第一个时间点到当前时间点都是表现良好时间段,因此更新 ans 为当前时间点 i+1。

7.如果 sum ≤ 0,则表明从第一个时间点到当前时间点出现了不劳累的时间段,需要判断是否有更长的表现良好时间段。

8.在 func longestWPI1 中,如果 m 中 sum-1 的值存在,则表明从之前的那个位置到当前位置,这段时间内有多于一个劳累的时间段与不劳累的时间段,则计算这个时间段长度,并与现有 ans 取最大值。若 m 中不存在,则将当前位置的值保存至 m[sum]。

9.在 func longestWPI2 中,计算出 sum-1+n 的值(n 表示 hours 数组长度的两倍,n<<1),并判断这个值在 early 数组中是否被保存过,如果有,则表明从之前的那个位置到当前位置,这段时间内有多于一个劳累的时间段与不劳累的时间段,则计算这个时间段长度,并与现有 ans 取最大值。若该值未被访问过,则将当前位置的值保存至 early[sum+n]。

10.遍历完 hours 后,返回 ans 值即可。

时间复杂度:

双函数中的 for 循环都只会遍历一次 hours 数组,所以时间复杂度为 O(n)。

空间复杂度:

func longestWPI1 中,使用了一个 map 类型的变量和三个 int 类型的变量,其中 map 的最大空间需求为 hours 数组长度,所以空间复杂度为 O(n)。

func longestWPI2 中,使用了一个长度为 2n+1 的 int 类型切片和三个 int 类型的变量,其中切片的最大空间需求为 2n+1,所以空间复杂度为 O(n)。

综上,两个函数的空间复杂度都为 O(n)。

go完整代码如下:

package main

import "fmt"

func longestWPI1(hours []int) int {
// key : 某个前缀和
// value : 这个前缀和最早出现的位置
var m = make(map[int]int)
m[0] = -1
var ans, sum int
for i, hour := range hours {
if hour > 8 {
sum++
} else {
sum--
}
if sum > 0 {
ans = i + 1
} else {
if j, ok := m[sum-1]; ok {
ans = Max(ans, i-j)
}
}
if _, ok := m[sum]; !ok {
m[sum] = i
}
}
return ans
} func longestWPI2(hours []int) int {
n := len(hours)
early := make([]int, (n<<1)+1)
for i := range early {
early[i] = -2
}
early[0+n] = -1
ans, sum := 0, 0
for i, hour := range hours {
if hour > 8 {
sum++
} else {
sum--
}
if sum > 1 {
ans = i + 1
} else {
index := sum - 1 + n
if index >= 0 && early[index] != -2 {
ans = Max(ans, i-early[index])
}
}
if early[sum+n] == -2 {
early[sum+n] = i
}
}
return ans
} func Max(x, y int) int {
if x > y {
return x
}
return y
} func main() {
hours := []int{9, 9, 6, 0, 6, 6, 9}
ans1 := longestWPI1(hours)
ans2 := longestWPI2(hours)
fmt.Println("ans1:", ans1)
fmt.Println("ans2:", ans2)
}

rust完整代码如下:

fn longest_wpi1(hours: Vec<i32>) -> i32 {
let mut map = std::collections::HashMap::<i32, i32>::new();
map.insert(0, -1);
let mut ans = 0;
let mut sum = 0;
for (i, hour) in hours.iter().enumerate() {
sum += if *hour > 8 { 1 } else { -1 };
if sum > 0 {
ans = i as i32 + 1;
} else {
if let Some(j) = map.get(&(sum - 1)) {
ans = ans.max(i as i32 - j);
}
}
map.entry(sum).or_insert(i as i32);
}
ans
} fn longest_wpi2(hours: Vec<i32>) -> i32 {
let n = hours.len();
let mut early = vec![-2; (n << 1) + 1];
early[n] = -1;
let mut ans = 0;
let mut sum = 0;
let mut i = 0;
while i < n {
sum += if hours[i] > 8 { 1 } else { -1 };
if sum > 1 {
ans = i as i32 + 1;
} else {
let index = sum - 1 + n as i32;
if index >= 0 && early[index as usize] != -2 {
ans = ans.max(i as i32 - early[index as usize])
}
}
if early[(sum + n as i32) as usize] == -2 {
early[(sum + n as i32) as usize] = i as i32;
}
i += 1;
}
ans
} fn main() {
let hours = vec![9, 9, 6, 0, 6, 6, 9];
let ans1 = longest_wpi1(hours.clone());
let ans2 = longest_wpi2(hours);
println!("ans1: {}", ans1);
println!("ans2: {}", ans2);
}

c++完整代码如下:

#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std; int longestWPI1(vector<int>& hours) {
// key : 某个前缀和
// value : 这个前缀和最早出现的位置
unordered_map<int, int> mp;
// 0这个前缀和,最早出现在哪?一个数也没有的时候
mp[0] = -1;
int ans = 0;
int sum = 0;
for (int i = 0; i < hours.size(); i++) {
sum += hours[i] > 8 ? 1 : -1;
if (sum > 0) {
// 0...i i+1
ans = i + 1;
}
else {
// sum = -4
// -5最早出现在哪 j j+1...i
if (mp.count(sum - 1)) {
ans = max(ans, i - mp[sum - 1]);
}
}
if (!mp.count(sum)) {
mp[sum] = i;
}
}
return ans;
} int longestWPI2(vector<int>& hours) {
int n = hours.size();
vector<int> early((n << 1) + 1, -2);
early[0 + n] = -1;
int ans = 0;
int sum = 0;
for (int i = 0; i < hours.size(); i++) {
sum += hours[i] > 8 ? 1 : -1;
if (sum > 1) {
ans = i + 1;
}
else {
if (sum - 1 + n >= 0 && early[sum - 1 + n] != -2) {
ans = max(ans, i - early[sum - 1 + n]);
}
}
if (early[sum + n] == -2) {
early[sum + n] = i;
}
}
return ans;
} int main() {
vector<int> hours = { 9, 9, 6, 0, 6, 6, 9 };
int ans1 = longestWPI1(hours);
int ans2 = longestWPI2(hours);
cout << "ans1: " << ans1 << endl;
cout << "ans2: " << ans2 << endl;
return 0;
}

c语言完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h> int longestWPI1(int* hours, int hoursSize) {
// key : 某个前缀和
// value : 这个前缀和最早出现的位置
int* mp = (int*)malloc(sizeof(int) * 20002);
memset(mp, -1, sizeof(int) * 20002);
// 0这个前缀和,最早出现在哪?一个数也没有的时候
mp[10000] = -1;
int ans = 0;
int sum = 0;
for (int i = 0; i < hoursSize; i++) {
sum += hours[i] > 8 ? 1 : -1;
if (sum > 0) {
// 0...i i+1
ans = i + 1;
}
else {
// sum = -4
// -5最早出现在哪 j j+1...i
if (mp[sum - 1 + 10000] != -1) {
ans = ans > (i - mp[sum - 1 + 10000]) ? ans : (i - mp[sum - 1 + 10000]);
}
}
if (mp[sum + 10000] == -1) {
mp[sum + 10000] = i;
}
}
free(mp);
return ans;
} // 数组替代哈希表
int longestWPI2(int* hours, int hoursSize) {
int n = hoursSize;
int* early = (int*)malloc(sizeof(int) * (n << 1 | 1));
for (int i = 0; i < (n << 1 | 1); i++) {
early[i] = -2;
}
early[0 + n] = -1;
int ans = 0;
int sum = 0;
for (int i = 0; i < hoursSize; i++) {
sum += hours[i] > 8 ? 1 : -1;
if (sum > 1) {
ans = i + 1;
}
else {
if (sum - 1 + n >= 0 && early[sum - 1 + n] != -2) {
ans = ans > (i - early[sum - 1 + n]) ? ans : (i - early[sum - 1 + n]);
}
}
if (early[sum + n] == -2) {
early[sum + n] = i;
}
}
free(early);
return ans;
} int main() {
int hours[7] = { 9, 9, 6, 0, 6, 6, 9 };
int ans1 = longestWPI1(hours, 7);
int ans2 = longestWPI2(hours, 7);
printf("ans1: %d\n", ans1);
printf("ans2: %d\n", ans2);
return 0;
}

2023-06-16:给你一份工作时间表 hours,上面记录着某一位员工每天的工作小时数。 我们认为当员工一天中的工作小时数大于 8 小时的时候,那么这一天就是「劳累的一天」。 所谓「表现良好的时间的更多相关文章

  1. 2023.1.16[模板]BSGS/exBSGS

    2023.1.16 [模板]BSGS/exBSGS 全称Boy Step Girl Step 给定一个质数 p,以及一个整数 a,一个整数 b,现在要求你计算一个最小的非负整数 l, 满足\(a^x ...

  2. 谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。

    谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数. Google2009华南地 ...

  3. 查询出menupath字段中 出现 “- "(横杆)大于3次的 记录

  4. Oracle中的rownum不能使用大于>的问题

    标题:Oracle中的rownum不能使用大于>的问题 一.对rownum的说明 关于Oracle 的 rownum 问题,很多资料都说不支持SQL语句中的“>.>=.=.betwe ...

  5. 开源不到 48 小时获 35k star 的推荐算法「GitHub 热点速览」

    本周的热点除了 GPT 各类衍生品之外,还多了一个被马斯克预告过.在愚人节开源出来的推特推荐算法,开源不到 2 天就有了 35k+ 的 star,有意思的是,除了推荐算法本身之外,阅读源码的工程师们甚 ...

  6. AtCoder Beginner Contest 100 2018/06/16

    A - Happy Birthday! Time limit : 2sec / Memory limit : 1000MB Score: 100 points Problem Statement E8 ...

  7. [每日一题2020.06.16] leetcode双周赛T3 5423 找两个和为目标值且不重叠的子数组 DP, 前缀和

    题目链接 给你一个整数数组 arr 和一个整数值 target . 请你在 arr 中找 两个互不重叠的子数组 且它们的和都等于 target .可能会有多种方案,请你返回满足要求的两个子数组长度和的 ...

  8. 2016/06/16 phpexcel

      程序部分   require_once './phpexcel/PHPExcel.php';   // 首先创建一个新的对象  PHPExcel object $objPHPExcel = new ...

  9. 【NLP新闻-2013.06.16】Representative Reviewing

    英语原文地址:http://nlp.hivefire.com/articles/share/40221/ 注:本人翻译NLP新闻只为学习专业英语和扩展视野,如果翻译的不好,请谅解! (实在是读不大懂, ...

  10. 【Azure 应用服务】PHP应用部署在App Service for Linux环境中,上传文件大于1MB时,遇见了413 Request Entity Too Large 错误的解决方法

    问题描述 在PHP项目部署在App Service后,上传文件如果大于1MB就会遇见 413 Request Entity Too Large 的问题. 问题解决 目前这个问题,首先需要分析应用所在的 ...

随机推荐

  1. Rainbond的 Gateway API 插件制作实践

    Gateway API 作为新一代的流量管理标准,对原有 Ingress 的扩展不规范.移植性差等问题做出了改进.从兼容K8s生态和优化网关体验出发,Rainbond 支持以插件的形式扩展平台网关能力 ...

  2. OWASP TOP 10 2021

    OWASP TOP 10 2021 2021 年的 TOP 10 中有 3 个新类别.4 个更改了名称和范围的类别以及一些合并. A01. 失效的访问控制 Broken Access Control ...

  3. ICMP隐蔽隧道攻击分析与检测(四)

    • ICMP隧道攻击通讯特征和特征提取 一.ICMP Ping正常通讯特征总结 一个正常的 ping 每秒最多只会发送两个数据包,而使用 ICMP隧道的服务器在同一时间会产生大量 ICMP 数据包 正 ...

  4. [Spring MVC]@RequestMapping 与 @RequestMapping+@RequestResponse的区别

    假定:返回格式均为JSON,JSON实体对象myJson的属性有:data.message.code.status. 二者的区别在于: @RequestMapping:会在最外层包裹 data属性,将 ...

  5. Redis 日志showlog 和 管道pileline

    redis日志 slowlog-log-slower-than:指定执行时间超过多少微秒(1秒等于1000000微秒) 的命令请求会被记录到日志上 slowlog-max-len:指定服务器最多保存多 ...

  6. 【vue3-element-admin】Husky + Lint-staged + Commitlint + Commitizen + cz-git 配置 Git 提交规范

    前言 本文介绍 vue3-element-admin 如何通过 Husky + Lint-staged + Commitlint + Commitizen + cz-git 来配置 Git 提交代码规 ...

  7. 10分钟极速入门dash应用开发

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/dash-master 大家好我是费老师,几天前我发布了由我开源维护的dash通用网页组件库fac的0 ...

  8. 3.2 构造器、this、包机制、访问修饰符、封装

    构造器 构造器:在实例化的一个对象的时候会给对象赋予初始值,因此我们可以通过修改构造器,来改变对象的初始值,构造器是完成对象的初始化,并不是创建对象 我们也可以创建多个构造器实现不同的初始化,即构造器 ...

  9. flume组件以及通过命令监控大数据平台转态

    实验一.Flume 组件安装配置 1.下载和解压 Flume 可 以 从 官 网 下 载 Flume 组 件 安 装 包 , 下 载 地 址 如 下 URL 链 接 所 示 https://archi ...

  10. Python 项目:外星人入侵--第三部分

    1.项目内容: 在屏幕左上角添加一个外星人,并指定合适的边框,根据第一个外星人的边距和屏幕尺寸计算屏幕上可容纳多少个外星人. 让外星人群向两边和下方移动,直到外星人被全部击落,有外星人撞到飞船,或有外 ...