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

    你可能感兴趣的文章
    Node-RED中实现HTML表单提交和获取提交的内容
    查看>>
    Node-RED中将CSV数据写入txt文件并从文件中读取解析数据
    查看>>
    Node-RED中建立TCP服务端和客户端
    查看>>
    Node-RED中建立Websocket客户端连接
    查看>>
    Node-RED中建立静态网页和动态网页内容
    查看>>
    Node-RED中解析高德地图天气api的json数据显示天气仪表盘
    查看>>
    Node-RED中连接Mysql数据库并实现增删改查的操作
    查看>>
    Node-RED中通过node-red-ui-webcam节点实现访问摄像头并截取照片预览
    查看>>
    Node-RED中配置周期性执行、指定时间阶段执行、指定时间执行事件
    查看>>
    Node-RED安装图形化节点dashboard实现订阅mqtt主题并在仪表盘中显示温度
    查看>>
    Node-RED怎样导出导入流程为json文件
    查看>>
    Node-RED订阅MQTT主题并调试数据
    查看>>
    Node-RED通过npm安装的方式对应卸载
    查看>>
    node-request模块
    查看>>
    node-static 任意文件读取漏洞复现(CVE-2023-26111)
    查看>>
    Node.js 8 中的 util.promisify的详解
    查看>>
    node.js debug在webstrom工具
    查看>>
    Node.js HTTP模块详解:创建服务器、响应请求与客户端请求
    查看>>
    Node.js RESTful API如何使用?
    查看>>
    node.js url模块
    查看>>