博客
关于我
【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/

    你可能感兴趣的文章
    OpenCV与AI深度学习 | 如何使用YOLOv9分割图像中的对象
    查看>>
    OpenCV与AI深度学习 | 如何使用YOLOv9检测图片和视频中的目标
    查看>>
    OpenCV与AI深度学习 | 如何在 Docker 容器中使用 GPU
    查看>>
    OpenCV与AI深度学习 | 实战 | OpenCV中更稳更快的找圆方法--EdgeDrawing使用演示(详细步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战 | OpenCV传统方法实现密集圆形分割与计数(详细步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战 | OpenCV实现扫描文本矫正应用与实现详解(附源码)
    查看>>
    OpenCV与AI深度学习 | 实战 | YOLO11自定义数据集训练实现缺陷检测 (标注+训练+预测 保姆级教程)
    查看>>
    OpenCV与AI深度学习 | 实战 | YOLOv10模型微调检测肾结石并提高准确率
    查看>>
    OpenCV与AI深度学习 | 实战 | 使用OpenCV和Streamlit搭建虚拟化妆应用程序(附源码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 使用OpenCV确定对象的方向(附源码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 使用YOLOv8 Pose实现瑜伽姿势识别
    查看>>
    OpenCV与AI深度学习 | 实战 | 使用YoloV8实例分割识别猪的姿态(含数据集)
    查看>>
    OpenCV与AI深度学习 | 实战 | 使用姿态估计算法构建简单的健身训练辅助应用程序
    查看>>
    OpenCV与AI深度学习 | 实战 | 基于OpenCV和K-Means聚类实现颜色分割(步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 基于YoloV5和Mask RCNN实现汽车表面划痕检测(步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 基于YOLOv9+SAM实现动态目标检测和分割(步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 基于YOLOv9和OpenCV实现车辆跟踪计数(步骤 + 源码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 文本图片去水印--同时保持文本原始色彩(附源码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 通过微调SegFormer改进车道检测效果(数据集 + 源码)
    查看>>
    OpenCV与AI深度学习 | 实战—使用YOLOv8图像分割实现路面坑洞检测(步骤 + 代码)
    查看>>