题目描述

✅ 1732. 找到最高海拔

image-20260928234305133

题意分析

路线起点海拔为零,gain[i] 表示从第 i 个地点到第 i + 1 个地点的海拔变化。正数表示上升,负数表示下降,零表示海拔不变,求整条路线到达过的最高海拔。

输入给的是相邻地点的差值,不是各地点本身的海拔,也不是只求某段爬升的最大增量。n 段变化对应 n + 1 个地点,起点同样需要参与最高值比较。

解法:滚动前缀和记录最高点

核心思路

[!blue]

当前海拔由前一个地点的海拔加本段变化得到。从零出发,走过前若干段后的海拔,就是这些 gain 的前缀和,因此按输入顺序累加即可还原每个地点的海拔。

用 cur 保存当前地点的海拔,用 ans 保存此前到达过的最高值。每读取一段变化,先执行 cur += g 到达下一个地点,再用新的 cur 更新最大值。处理完前 i 段后,cur 对应第 i 个地点,ans 已覆盖从起点到这里的全部地点。

两个变量都初始化为零:cur 表示还没出发,ans 则把起点纳入候选。如果之后所有地点都低于起点,答案仍然正确保留为零。下降路段不能忽略,也不能把负海拔重置为零,因为后面的每次上升都以真实的当前海拔为基础。

只需要最高值,不需要输出各地点海拔,所以前缀和可以滚动保存在一个变量中,无须创建完整前缀数组。

解题步骤

  1. 将当前海拔 cur 和最高海拔 ans 都设为零。
  2. 按顺序读取每段变化,先加到 cur,恢复下一个地点的海拔。
  3. 将 ans 更新为原最高值与当前海拔中的较大者。
  4. 所有路段处理完后返回 ans。

代码实现

class Solution {
    public int largestAltitude(int[] gain) {
        // 答案初值即起点海拔 0,因为起点也是到达过的位置
        int ans = 0;
        // 当前海拔,滚动保存 gain 的前缀和
        int cur = 0;

        for (int g : gain) {
            // 累加净变化,推进到下一个位置的海拔
            cur += g;
            // 累加之后再比较,保证每个位置都被纳入
            ans = Math.max(ans, cur);
        }

        return ans;
    }
}
func largestAltitude(gain []int) int {
    // ans 初值即起点海拔 0;cur 滚动保存 gain 的前缀和
    ans, cur := 0, 0
    for _, g := range gain {
        // 累加净变化,推进到下一个位置的海拔
        cur += g
        if cur > ans {
            // 累加之后再比较,保证每个位置都被纳入
            ans = cur
        }
    }

    return ans
}

复杂度分析

  • 时间复杂度:$O(n)$,每段海拔变化读取一次,每次只做一次累加和比较。
  • 空间复杂度:$O(1)$,仅保存当前海拔和历史最大值,不修改输入。

关键点总结

[!green]

  • 地点海拔是从起点开始的前缀和,单段变化本身不代表所在高度。
  • 初始答案零负责计入第一个地点,后续每轮负责计入一个新地点。
  • 当前值与历史最大值职责不同,只保留最大值无法继续还原下一地点。

易错点总结

[!yellow]

  • 把最大的 gain 当成最高海拔,忽略了此前路段的累计影响。
  • 只累加上升路段或把负海拔归零,会改变真实路线高度。
  • 遗漏起点,整条路线低于零时就会错误返回负数。
  • 在累加本段变化前才比较,若循环结束不再更新,会漏掉最终地点。

相似题目

题目 难度 关联与区别
1480. 一维数组的动态和 简单 同样通过前缀累加恢复每个位置的累计值,本题只取最大值所以无需保存整个结果数组。
303. 区域和检索 - 数组不可变 简单 同样利用前缀和表示累计量,原题保留数组供多次区间查询,本题一遍扫描即可。
转载与许可
作者
链接 https://hgnulb.github.io/blog/2026/60859911
许可 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!