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. 浅谈Array --JavaScript内置对象

    Array --JavaScript内置对象 描述 可以用一个变量存储多种数据类型的Array对象,Array不是关联数组,不能使用字符串作为索引访问数组元素,需要使用非负整数的下标访问数组中的元素. ...

  2. jq-ajax-get

    get有三个参数,第一个时候url,第二个是数据,第三个是回调函数(可以用返回值表示,如下所示) 执行正确时,返回的依次是res,type,xhr. 执行错误连接不上的的依次是xhr,type,res ...

  3. Windows 11 Update Download Error Solution - 0x80248007

    I had the same issue on a Windows 2019 virtual server while performing routine windows updates. The ...

  4. 免费注册 Redhat 开发者并且进行订阅和激活

    注册 一.进入 https://www.redhat.com/wapps/ugc/register.html 进行注册 二.然后通过这个网址进入开发者平台 https://developers.red ...

  5. HOOPS Exchange助力Shapr3D产品实现了“无障碍的用户体验”

    HOOPS SDK是用于3D工业软件开发的工具包,其中包括4款工具,分别是用于 读取和写入30多种CAD文件格式的HOOPS Exchange.专注于Web端工程图形渲染的HOOPS Communic ...

  6. 连接MongoDB+Docker安装MongoDB

    一.连接MongoDB 工具:studio 3T 下载:https://studio3t.com/download-thank-you/?OS=win64 1.无设置密码 最终成功页面 2.设置了密码 ...

  7. Docker Compose 部署 Jenkins

    Jenkins介绍 Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具 Jenkins应用广泛,大多数互联网公司都采用Jenkins配合GitLab.Docker.K8s作为实现D ...

  8. C# 从0到实战 lambda表达式和Expression-bodied表达式

    什么是lambda表达式(λ表达式) 用过其他函数式语言的人可能对闭包和惰性计算很熟悉,没有用过的人也多多少少的听说过Lambda表达式.那么到底什么是lambda表达式呢?按我的看法是创建一个匿名的 ...

  9. C# 组合键判断

    e.KeyboardDevice.Modifiers 同时按下了Ctrl + H键(H要最后按,因为判断了此次事件的e.Key)修饰键只能按下Ctrl,如果还同时按下了其他修饰键,则不会进入 1 pr ...

  10. Redis之消息队列实现

    文章目录 秒杀场景 采用消息队列实现 List实现消息队列 PubSub(发布订阅)实现消息队列 基于Stream实现消息队列 消费者组 实践 总结 秒杀问题是非常重要且比较难实现的,如果不进行架构的 ...