2026-09-10:维持亮度的最小总能量。用go语言,有 n 个灯泡排成一行,位置编号从 0 到 n-1。时间按离散单位划分,每个单位时间都可以独立

网易专栏1个月前发布 admin
28 0 0

🤖 AI总结

主题

求解满足亮度要求的灯泡最小总能量消耗问题。

摘要

通过合并区间求总时长,并计算每单位所需最少灯泡数,乘积得出最小总能量。

关键信息

  • 1 合并重叠区间计算总覆盖时间
  • 2 每个时间单位最少灯泡数为ceil(brightness/3)
  • 3 总能量为灯泡数乘以总时间

2026-09-10:维持亮度的最小总能量。用go语言,有 n 个灯泡排成一行,位置编号从 0 到 n-1。时间按离散单位划分,每个单位时间都可以独立决定每个灯泡是开还是关。一个开启的灯泡会照亮它自己的位置,以及左右相邻的位置,如果这些位置存在的话。一个单位时间内的照明总量,等于至少被一个开启灯泡照到的不同位置数量;同一个位置即使被多个灯泡照亮,也只算一次。

另外给定一个亮度要求 brightness,以及若干个闭时间区间。对于被这些区间中任意一个覆盖到的单位时间,照明总量必须达到或超过 brightness。对于没有被任何区间覆盖的单位时间,没有照明要求,灯泡可以全部关闭。

每开启一个灯泡一个单位时间,就消耗 1 单位能量。目标是在满足所有区间内照明要求的前提下,使总能量消耗尽可能小,并返回这个最小总能量。

1 <= n <= 1000000。

1 <= brightness <= n。

1 <= intervals.length <= 100000。

intervals[i] == [starti, endi]。

0 <= starti <= endi <= 1000000000。

输入: n = 5, brightness = 5, intervals = [[6,12]]。

输出: 14。

解释:

开启位于位置 1 和 4 的灯泡。

当前序列状态:0 1 0 0 1.

全部 5 个位置都被照亮,因此达到了要求的亮度。

有效区间长度为 12 – 6 + 1 = 7,因此总能量为 2 * 7 = 14。

题目来自力扣3951。

代码逻辑分步详解 第1步:排序区间

• 输入intervals是若干闭区间[start, end],表示这些时间单位必须满足亮度要求。

  • • 首先按区间的左端点从小到大排序,这是为了后续合并重叠区间。

    第2步:合并重叠区间(求总覆盖时间长度)

    • 因为如果两个区间在时间上有重叠,那么重叠部分只需要满足一次亮度要求即可(但实际照明是连续时间,不需要重复计算)。

  • • 合并规则:

  • • 初始化left=0,right=-1(表示当前合并区间为空)。

  • • 遍历排序后的每个区间[p[0], p[1]]:

  • • 如果当前区间的左端点p[0]≤ 当前合并区间的右端点right,说明有重叠或相邻,可以合并,更新right = max(right, p[1])。

  • • 否则(不相交),则说明当前合并区间结束,将它的长度(right - left + 1)累加到sumLen,然后开始一个新的合并区间left=p[0], right=p[1]。

  • • 遍历结束后,将最后一个合并区间的长度也累加到sumLen。

  • •结果:sumLen是所有必须满足亮度要求的时间单位总数(去重后)。

    第3步:计算单时间单位所需最少灯泡数

    • 一个灯泡最多照亮 3 个位置(自身+左右)。

  • • 要照亮至少brightness个不同位置,最少需要bulbs = ceil(brightness / 3)个灯泡。

  • • 代码中(brightness + 2) / 3就是向上取整。

    第4步:计算最小总能量

    • 每个时间单位需要bulbs个灯泡,共sumLen个时间单位。

  • • 总能量 =bulbs × sumLen。

  • • 返回int64类型,因为结果可能较大。

    针对给定示例的模拟计算

    • 输入:n=5, brightness=5, intervals=[[6,12]]

  • • 排序(只有一个区间,无需合并):

  • •sumLen = 12 - 6 + 1 = 7

  • •bulbs = (5+2)/3 = 7/3 = 2.333... → 2(向上取整)

  • • 总能量 =2 × 7 = 14,与题目输出一致。

    时间复杂度分析

    •排序:O(k log k),其中k = len(intervals),最多 100000。

  • •合并区间遍历:O(k)。

  • • 整体时间复杂度:O(k log k),主要受排序限制。

    额外空间复杂度分析

    • 排序通常需要O(log k)的栈空间(递归深度)或O(1)的原地排序(如 Go 的slices.SortFunc使用快速排序,平均栈空间O(log k))。

  • • 除了输入数组外,只使用了少数几个变量(sumLen,left,right,bulbs),额外空间为O(1)(忽略排序的栈开销)。

  • • 若严格考虑排序辅助空间,可认为是O(log k),但通常描述为O(1)额外空间(不计输入和排序临时空间)。

    最终答案总结

    •过程:排序区间 → 合并求总覆盖时间长度 → 计算所需最少灯泡数 → 乘积得最小总能量。

  • •时间复杂度:O(k log k),k 为区间数量。

  • •额外空间复杂度:O(1)(或O(log k)含排序栈空间,但通常视为常数级)。

    Go完整代码如下:

    package main

    import (
    "fmt"
    "slices"
    )

    func minEnergy(_, brightness int, intervals [][]int) int64 {
    slices.SortFunc(intervals, func(p, q []int) int { return p[0] - q[0] }) // 按照左端点从小到大排序

    // 56. 合并区间(只计算区间长度之和)
    sumLen := 0
    left, right := 0, -1
    for _, p := range intervals {
    if p[0] <= right { // 左端点在合并区间内,可以合并
    right = max(right, p[1]) // 更新合并区间的右端点
    } else { // 不相交,无法合并
    sumLen += right - left + 1
    left, right = p[0], p[1] // 新的合并区间
    }
    }
    sumLen += right - left + 1

    bulbs := (brightness + 2) / 3 // 至少要开启 bulbs 个灯泡
    return int64(bulbs * sumLen)
    }

    func main() {
    n := 5
    brightness := 5
    intervals := [][]int{{6, 12}}
    result := minEnergy(n, brightness, intervals)
    fmt.Println(result)
    }

    2026-09-10:维持亮度的最小总能量。用go语言,有 n 个灯泡排成一行,位置编号从 0 到 n-1。时间按离散单位划分,每个单位时间都可以独立

    Python完整代码如下:

    # -*-coding:utf-8-*-

    def min_energy(_, brightness: int, intervals: list[list[int]]) -> int:
    # 按左端点从小到大排序
    intervals.sort(key=lambda x: x[0])

    # 合并区间,并计算所有区间的总长度(闭区间长度)
    total_len = 0
    left, right = 0, -1
    for start, end in intervals:
    if start <= right: # 当前区间与合并区间重叠
    right = max(right, end)
    else: # 开始新的合并区间
    total_len += right - left + 1
    left, right = start, end
    total_len += right - left + 1 # 加上最后一个合并区间

    # 至少需要开启的灯泡数量:ceil(brightness / 3)
    bulbs = (brightness + 2) // 3

    return bulbs * total_len

    if __name__ == "__main__":
    n = 5
    brightness = 5
    intervals = [[6, 12]]
    result = min_energy(n, brightness, intervals)
    print(result)

    2026-09-10:维持亮度的最小总能量。用go语言,有 n 个灯泡排成一行,位置编号从 0 到 n-1。时间按离散单位划分,每个单位时间都可以独立

    C++完整代码如下:

      
    



    using namespace std;

    long long minEnergy(int /* n 未使用 */, int brightness, vector int >>& intervals) {
    // 按左端点从小到大排序
    sort(intervals.begin(), intervals.end(),
    []( const vector< int >& a, const vector< int >& b) {
    return a[ 0 ] < b[ 0 ];
    });

    // 合并区间,计算所有区间的总长度(闭区间)
    long long sumLen = 0 ;
    int left = 0 , right = -1 ;
    for ( const auto& p : intervals) {
    int start = p[ 0 ], end = p[ 1 ];
    if (start <= right) { // 区间重叠或相邻,可以合并
    right = max(right, end);
    } else { // 开始新的合并区间
    sumLen += right - left + 1 ;
    left = start;
    right = end;
    }
    }
    sumLen += right - left + 1 ; // 加上最后一个合并区间

    // 至少需要开启的灯泡数量:ceil(brightness / 3)
    long long bulbs = (brightness + 2 ) / 3 ;

    return bulbs * sumLen;
    }

    int main() {
    int n = 5 ;
    int brightness = 5 ;
    vector int >> intervals = {{ 6 , 12 }};

    long long result = minEnergy(n, brightness, intervals);
    cout << result << endl;

    return 0 ;
    }

    2026-09-10:维持亮度的最小总能量。用go语言,有 n 个灯泡排成一行,位置编号从 0 到 n-1。时间按离散单位划分,每个单位时间都可以独立

    我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。

    © 版权声明

    相关文章