华为OD机考双机位C卷 - 最佳升级时间窗(Java & Python & JS & GO & C++ & C)

最佳升级时间窗

2026华为OD机试双机位C卷 - 华为OD上机考试双机位C卷

华为OD机试双机位C卷真题目录点击查看: 【全网首发】2026华为OD机位C卷 机考真题题库含考点说明以及在线OJ(OD上机考试双机位C卷)

题目描述

有一套系统需升级,为减小系统升级期间的影响,需根据系统过去一段时间内的每小时平均访问数据,来预测最佳升级时间窗。

现给长度为168(7*24)的整数数组,表示一个周期(假设从周一00:00到周日24:00)的每小时历史数据,最佳升级时间窗选择规则如下:

1:时间窗内累计用户访问量必须小于等于给定的容忍值。

2:时间窗必须是连续的x个小时,最大的x即为最佳升级时间窗,且不超过7*24.

3:时间窗允许跨周期,例如当前周期的第167小时到下一周期的第166小时,是一个长度为168的时间窗。

请计算最佳升级时间窗,并返回其开始时间和结束时间的数组下标。如果存在多个最佳升级时间窗,返回开始时间下标最小的一个

输入描述

第一行为整数n,表示给定的升级影响的容忍值,取值范围:[0, 2^31]。

第二行为7 * 24个整数,表示一个周期(7*24)的每个小时用户访问量,每个值的范围:[0, 2^31]。

输出描述

两个整数,分别表示所计算出的最佳升级时间窗的开始时间下标(包含)和结束时间下标(包含),不存在时返回 -1 -1 。

示例1

输入

6
1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1

输出

22 25

说明

最佳升级窗口为:2 1 1 2

解题思路

核心思想

本题要求在一个长度为 168(7天 x 24小时)的循环数组中,找到最长的连续子数组,使得其和不超过给定的容忍值。

  1. 滑动窗口(Sliding Window)
    • 这是一个经典的滑动窗口问题。我们需要维护一个窗口 [left, right],使得窗口内的元素和 sum 小于等于容忍值 tolerance
    • 为了处理“循环数组”和“跨周期”的问题,我们可以将原数组复制一份拼接到后面,形成一个长度为 336 的数组。这样,跨越末尾的窗口就变成了连续的窗口。
  2. 窗口扩展与收缩
    • 扩展right 指针向右移动,将新元素加入窗口,增加 sum
    • 收缩:如果 sum > tolerance,则 left 指针向右移动,移出最左边的元素,减少 sum,直到 sum <= tolerance
  3. 约束条件
    • 窗口长度不能超过 168。如果 right - left + 1 > 168,也需要收缩左边界。
  4. 结果记录
    • 在每次窗口合法时,检查窗口长度 length = right - left + 1
    • 如果 length > max_len,更新最大长度,并记录当前的起始位置。
    • 由于题目要求“如果存在多个最佳升级时间窗,返回开始时间下标最小的一个”,我们需要注意:
      • 我们在遍历长度为 2N 的数组时,可能会遇到同一个窗口两次(一次在前半部分,一次在后半部分)。
      • 我们只关心起始下标 start_index = left % 168
      • 在更新最大长度时,如果长度相同,我们优先选择起始下标更小的。
      • 实际上,由于我们是从左向右遍历,如果我们在 left < 168 的时候找到了一个最优解,那么在 left >= 168 时找到的同构解(起始位置 +168)肯定不如之前的解优。
      • 但是,如果是长度相同的另一个解,我们应该在遇到第一个时就记录下来(因为此时下标最小),后续遇到相同长度的解如果不比当前优则不更新。

复杂度分析

  • 时间复杂度:$O(N)$。$N=168$。我们只遍历了 2 倍长度的数组。
  • 空间复杂度:$O(N)$。用于存储 2 倍长度的数组。
posted @ 2026-03-12 20:28  华为od算法大师  阅读(1)  评论(0)    收藏  举报