博客
关于我
【10月打卡~Leetcode每日一题】845. 数组中的最长山脉(难度:中等){补昨日}
阅读量:256 次
发布时间:2019-03-01

本文共 2366 字,大约阅读时间需要 7 分钟。

为了解决数组中的最长山脉问题,我们需要找到数组中的山峰和山谷,然后计算每个山峰到最近的两个山谷的距离,找出最大的那个作为最长的山脉长度。以下是详细的优化步骤:

步骤一:识别山峰和山谷

  • 遍历数组,从左到右检查每个元素是否是山峰或山谷。
    • 山峰:元素必须严格大于左右两个邻居。
    • 山谷:元素必须严格小于左右两个邻居。
  • 记录位置,将山峰和山谷的位置分别存储在两个列表中。
  • 步骤二:确定山脉的起点和终点

  • 处理边界情况,确保山峰不在数组的开头或结尾,因为这些位置无法成为山脉的起点或终点。
  • 收集所有可能的山脉起点,即每个山峰的位置。
  • 收集所有可能的山脉终点,即每个山谷的位置。
  • 步骤三:计算每个山脉的长度

  • 为每个山峰,找到其左边最近的山谷和右边最近的山谷。
  • 计算距离,山脉的长度为右边山谷到左边山谷的位置差减一。
  • 记录最长的山脉长度,在遍历所有山峰时更新最大值。
  • 步骤四:处理特殊情况

  • 数组长度小于2,直接返回0,因为无法形成山脉。
  • 山峰或山谷列表为空,直接返回0,因为没有山脉可以计算。
  • 山脉可能跨越数组边界,确保处理开头或结尾的山谷位置时,避免越界错误。
  • 优化实现

  • 线性遍历,在O(n)时间内完成山峰和山谷的识别。
  • 预处理,为每个位置记录最近的山谷位置,避免重复遍历,提升效率。
  • 二分查找,在预处理后,快速找到左边和右边最近的山谷,确保每个山峰的处理时间为O(log n)。
  • 代码示例

    class Solution:    def longestMountain(self, A: List[int]) -> int:        if len(A) < 3:            return 0                peaks = []        valleys = []        for i in range(len(A)):            # 检查是否为山峰            if A[i] > A[i-1] and A[i] > A[i+1]:                peaks.append(i)            # 检查是否为山谷            elif A[i] < A[i-1] and A[i] < A[i+1]:                valleys.append(i)                if not peaks:            return 0                max_length = 0        # 预处理:为每个位置记录最近的山谷位置        prev_valley = [-1] * len(A)        next_valley = [len(A)] * len(A)                # 找到每个位置的左边最近的山谷        for i in range(len(A)):            if A[i] < A[i-1] and A[i] < A[i+1]:                prev_valley[i] = i  # 这个位置是山谷                for j in range(i-1, -1, -1):                    if A[j] > A[j+1] and A[j] > A[j+2]:                        prev_valley[j+1] = j                        break                # 找到每个位置的右边最近的山谷        for i in range(len(A)-1, -1, -1):            if A[i] < A[i+1] and A[i] < A[i-1]:                next_valley[i] = i                for j in range(i+1, len(A)):                    if A[j] < A[j-1] and A[j] < A[j-2]:                        next_valley[j-2] = j                        break                # 计算每个山峰的山脉长度        for peak in peaks:            left = prev_valley[peak]            right = next_valley[peak]            if left == -1:                left = 0            if right == len(A):                right = len(A)-1            current_length = right - left + 1            if current_length > max_length:                max_length = current_length                return max_length

    优化效果

  • 时间复杂度:预处理阶段为O(n),遍历阶段为O(n),总体复杂度为O(n)。
  • 空间复杂度:使用额外的数组存储最近的山谷位置,空间复杂度为O(n)。
  • 可读性和可维护性:代码结构清晰,易于理解和修改。
  • 通过以上优化步骤,我们能够高效地解决数组中的最长山脉问题,确保在各种情况下都能得到正确的结果。

    转载地址:http://gqba.baihongyu.com/

    你可能感兴趣的文章
    Palo Alto Networks PAN-OS身份认证绕过导致RCE漏洞复现(CVE-2024-0012)
    查看>>
    Panalog 日志审计系统 libres_syn_delete.php 前台RCE漏洞复现
    查看>>
    Springboot中@SuppressWarnings注解详细解析
    查看>>
    Panalog 日志审计系统 sprog_deletevent.php SQL 注入漏洞复现
    查看>>
    Panalog 日志审计系统 sprog_upstatus.php SQL 注入漏洞复现(XVE-2024-5232)
    查看>>
    Panalog 日志审计系统 前台RCE漏洞复现
    查看>>
    PANDA VALUE_COUNTS包含GROUP BY之前的所有值
    查看>>
    pandas - 如何将所有列从对象转换为浮点类型
    查看>>
    Pandas - 按列分组并将数据转换为 numpy 数组
    查看>>
    Pandas - 按日期对日内时间序列进行分组
    查看>>
    Pandas - 有条件的删除重复项
    查看>>
    pandas -按连续日期时间段分组
    查看>>
    pandas -更改重新采样的时间序列的开始和结束日期
    查看>>
    SpringBoot+Vue+Redis前后端分离家具商城平台系统(源码+论文初稿直接运行《精品毕设》)15主要设计:用户登录、注册、商城分类、商品浏览、查看、购物车、订单、支付、以及后台的管理
    查看>>
    pandas :to_excel() float_format
    查看>>
    pandas :从数据透视表中的另一列中减去一列
    查看>>
    pandas :加入有条件的数据框
    查看>>