【数据结构和算法】找到最高海拔

简介: 这是力扣的 1732 题,难度为简单,解题方案有很多种,本文讲解我认为最奇妙的一种。这是一道非常经典的前缀和问题,虽然看似简单,但它却能让你深入理解前缀和的特点。有一个自行车手打算进行一场公路骑行,这条路线总共由n + 1个不同海拔的点组成。自行车手从海拔为0的点0开始骑行。给你一个长度为n的整数数组gain,其中gain[i]是点i和点i + 1的净海拔高度差(0

 其他系列文章导航

Java基础合集

数据结构与算法合集

设计模式合集

多线程合集

分布式合集

ES合集


文章目录

其他系列文章导航

文章目录

前言

一、题目描述

二、题解

2.1 前缀和的解题模板

2.1.1 最长递增子序列长度

2.1.2 寻找数组中第 k 大的元素

2.1.3 最长公共子序列长度

2.1.4 寻找数组中第 k 小的元素

2.2 方法一:前缀和(差分数组)

三、代码

3.2 方法一:前缀和(差分数组)

四、复杂度分析

4.2 方法一:前缀和(差分数组)


前言

这是力扣的 1732 题,难度为简单,解题方案有很多种,本文讲解我认为最奇妙的一种。

这是一道非常经典的前缀和问题,虽然看似简单,但它却能让你深入理解前缀和的特点。


一、题目描述

有一个自行车手打算进行一场公路骑行,这条路线总共由 n + 1 个不同海拔的点组成。自行车手从海拔为 0 的点 0 开始骑行。

给你一个长度为 n 的整数数组 gain ,其中 gain[i] 是点 i 和点 i + 1净海拔高度差0 <= i < n)。请你返回 最高点的海拔

示例 1:

输入:gain = [-5,1,5,0,-7]

输出:1

解释:海拔高度依次为 [0,-5,-4,1,1,-6] 。最高海拔为 1 。


示例 2:

输入:gain = [-4,-3,-2,-1,4,3,2]

输出:0

解释:海拔高度依次为 [0,-4,-7,-9,-10,-6,-3,-1] 。最高海拔为 0 。


提示:

    • n == gain.length
    • 1 <= n <= 100
    • -100 <= gain[i] <= 100

    二、题解

    2.1 前缀和的解题模板

    前缀和算法是一种在处理数组或链表问题时常用的技巧,它可以有效地减少重复计算,提高算法的效率。下面是一些常见的使用前缀和算法的题目以及解题思路:

    2.1.1 最长递增子序列长度

    题目描述:给定一个无序数组,求最长递增子序列的长度。

    解题思路:可以使用前缀和和单调栈来解决这个问题。首先,遍历数组,计算出前缀和。然后,使用单调栈记录当前递增子序列的起始位置。遍历数组时,如果当前元素大于前缀和,说明可以扩展当前递增子序列,将当前位置入栈。如果当前元素小于等于前缀和,说明当前递增子序列已经结束,弹出栈顶元素。最后,栈中剩余的元素即为最长递增子序列的起始位置,计算长度即可。

    2.1.2 寻找数组中第 k 大的元素

    题目描述:给定一个无序数组和一个整数k,找到数组中第k大的元素。

    解题思路:可以使用前缀和和快速选择算法来解决这个问题。首先,计算出数组的前缀和。然后,使用快速选择算法在数组中找到第k小的元素。具体实现中,每次选择一个枢轴元素,将数组分成两部分,小于枢轴的元素和大于枢轴的元素。如果枢轴左边的元素个数小于k,则在左边的子数组中继续查找;如果枢轴左边的元素个数大于等于k,则在右边的子数组中继续查找。最后,当找到第k小的元素时,返回该元素即可。

    2.1.3 最长公共子序列长度

    题目描述:给定两个字符串,求最长公共子序列的长度。

    解题思路:可以使用动态规划算法来解决这个问题。如果字符串长度分别为m和n,则可以定义一个二维数组dp[m+1][n+1],其中dp[i][j]表示字符串s1的前i个字符和字符串s2的前j个字符的最长公共子序列长度。根据动态规划的思想,状态转移方程为dp[i][j] = max(dp[i-1][j-1], dp[i-1][j], dp[i][j-1])。如果s1[i-1]等于s2[j-1],则dp[i][j] = dp[i-1][j-1] + 1;否则dp[i][j]取其他两种情况中的较大值。最终结果为dp[m][n]。

    2.1.4 寻找数组中第 k 小的元素

    题目描述:给定一个无序数组和一个整数k,找到数组中第k小的元素。

    解题思路:可以使用前缀和和快速选择算法来解决这个问题。具体实现与寻找第k大元素类似,只不过最后返回的是第k小的元素而非第k大的元素。

    2.2 方法一:前缀和(差分数组)

    解这个问题需要注意以下几点:

      1. 理解题意:首先,要明确题目的要求,理解自行车手的骑行路线和海拔变化的关系。根据题目描述,自行车手从海拔为0的点开始骑行,通过一系列的海拔变化,最终要找到最高点的海拔。
      2. 分析海拔变化:根据给定的gain数组,可以分析出自行车手的海拔变化。gain[i]表示点i和点i+1之间的净海拔高度差。通过累加这些高度差,可以计算出经过每个点后的总海拔变化。
      3. 确定最高点的海拔:在计算出总的海拔变化后,需要找到最高点的海拔。这可以通过比较累加海拔和初始海拔的大小来实现。最高点的海拔即为累加海拔和初始海拔中的较大值。
      4. 注意数组边界条件:在处理gain数组时,需要注意数组的边界条件。例如,gain[0]表示起点和终点之间的海拔高度差,而gain[n-1]表示倒数第二个点和终点之间的海拔高度差。
      5. 代码实现:最后,根据上述分析,可以使用Python等编程语言实现相应的算法。在实现过程中,需要注意代码的简洁性和可读性,同时也要注意处理可能的异常情况。

      思路与算法:

      我们假设每个点的海拔为 hi ,由于 gain[i] 表示第 i 个点和第 i+1 个点的海拔差,因此

      gain[i] = h(i+1) − hi,那么:

      image.gif编辑

      可以发现,每个点的海拔都可以通过前缀和的方式计算出来。因此,我们只需要遍历一遍数组,求出前缀和的最大值,即为最高点的海拔。

      实际上题目中的 gain 数组是一个差分数组,对差分数组求前缀和即可得到原海拔数组。然后求出原海拔数组的最大值即可。


      三、代码

      3.2 方法一:前缀和(差分数组)

      Java版本:

      class Solution {
          public int largestAltitude(int[] gain) {
          int high = 0, max = 0;
              for (int h : gain) {
                  high += h;
                  max = Math.max(max, high);
              }
              return max;
          }
      }

      image.gif

      C++版本:

      class Solution {
      public:
          int largestAltitude(std::vector<int>& gain) {
              int high = 0, max = 0;
              for (int h : gain) {
                  high += h;
                  max = std::max(max, high);
              }
              return max;
          }
      };

      image.gif

      Python版本:

      class Solution:
          def largestAltitude(self, gain: List[int]) -> int:
              high = 0
              max_altitude = 0
              for h in gain:
                  high += h
                  max_altitude = max(max_altitude, high)
              return max_altitude

      image.gif

      Go版本:

      func largestAltitude(gain []int) int {
          high, max := 0, 0
          for _, h := range gain {
              high += h
              if high > max {
                  max = high
              }
          }
          return max
      }
      func main() {
          gain := []int{-5, 1, 5, 0, -7}
          result := largestAltitude(gain)
          fmt.Println(result)
      }

      image.gif


      四、复杂度分析

      4.2 方法一:前缀和(差分数组)

        • 时间复杂度: O(n),其中 n 为数组 gain 的长度。
        • 空间复杂度: O(1)。


        目录
        相关文章
        |
        23天前
        |
        算法 数据处理 C语言
        C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
        本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
        34 1
        |
        26天前
        |
        机器学习/深度学习 算法 数据挖掘
        K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构
        K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构。本文介绍了K-means算法的基本原理,包括初始化、数据点分配与簇中心更新等步骤,以及如何在Python中实现该算法,最后讨论了其优缺点及应用场景。
        84 4
        |
        2月前
        |
        存储 人工智能 算法
        数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
        这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
        92 3
        数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
        |
        24天前
        |
        存储 算法 搜索推荐
        Python 中数据结构和算法的关系
        数据结构是算法的载体,算法是对数据结构的操作和运用。它们共同构成了计算机程序的核心,对于提高程序的质量和性能具有至关重要的作用
        |
        24天前
        |
        数据采集 存储 算法
        Python 中的数据结构和算法优化策略
        Python中的数据结构和算法如何进行优化?
        |
        1月前
        |
        算法
        数据结构之路由表查找算法(深度优先搜索和宽度优先搜索)
        在网络通信中,路由表用于指导数据包的传输路径。本文介绍了两种常用的路由表查找算法——深度优先算法(DFS)和宽度优先算法(BFS)。DFS使用栈实现,适合路径问题;BFS使用队列,保证找到最短路径。两者均能有效查找路由信息,但适用场景不同,需根据具体需求选择。文中还提供了这两种算法的核心代码及测试结果,验证了算法的有效性。
        97 23
        |
        1月前
        |
        算法
        数据结构之蜜蜂算法
        蜜蜂算法是一种受蜜蜂觅食行为启发的优化算法,通过模拟蜜蜂的群体智能来解决优化问题。本文介绍了蜜蜂算法的基本原理、数据结构设计、核心代码实现及算法优缺点。算法通过迭代更新蜜蜂位置,逐步优化适应度,最终找到问题的最优解。代码实现了单链表结构,用于管理蜜蜂节点,并通过适应度计算、节点移动等操作实现算法的核心功能。蜜蜂算法具有全局寻优能力强、参数设置简单等优点,但也存在对初始化参数敏感、计算复杂度高等缺点。
        60 20
        |
        23天前
        |
        并行计算 算法 测试技术
        C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
        C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
        54 1
        |
        1月前
        |
        机器学习/深度学习 算法 C++
        数据结构之鲸鱼算法
        鲸鱼算法(Whale Optimization Algorithm,WOA)是由伊朗研究员Seyedali Mirjalili于2016年提出的一种基于群体智能的全局优化算法,灵感源自鲸鱼捕食时的群体协作行为。该算法通过模拟鲸鱼的围捕猎物和喷出气泡网的行为,结合全局搜索和局部搜索策略,有效解决了复杂问题的优化需求。其应用广泛,涵盖函数优化、机器学习、图像处理等领域。鲸鱼算法以其简单直观的特点,成为初学者友好型的优化工具,但同时也存在参数敏感、可能陷入局部最优等问题。提供的C++代码示例展示了算法的基本实现和运行过程。
        50 0
        |
        1月前
        |
        算法 vr&ar 计算机视觉
        数据结构之洪水填充算法(DFS)
        洪水填充算法是一种基于深度优先搜索(DFS)的图像处理技术,主要用于区域填充和图像分割。通过递归或栈的方式探索图像中的连通区域并进行颜色替换。本文介绍了算法的基本原理、数据结构设计(如链表和栈)、核心代码实现及应用实例,展示了算法在图像编辑等领域的高效性和灵活性。同时,文中也讨论了算法的优缺点,如实现简单但可能存在堆栈溢出的风险等。
        42 0