当前位置: 首页 > article >正文

LeetCode--152. 最大乘积子数组【DP】

152. 乘积最大子数组


正文

给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续 子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。

测试用例的答案是一个 32-位 整数。

如题给定一个数组,求连续子数组最大乘积

第一次看见这道题的思路是用动态规划,计算前缀乘积,但是这样一来时间复杂度很高,前缀为0以及负数的情况很难处理。

更好的思路应该是同时统计前缀的最大值和最小值,因为最小值在遇到负数之后会变成最大值,而最大值会变成最小值,通过max嵌套来处理前缀为0的情况,下面是未经优化的代码:

vfunc maxProduct(nums []int) int {
    n := len(nums)
    maxF := make([]int, n)
    minF := make([]int, n)
    
    maxF[0] = nums[0]
    minF[0] = nums[0]
    
    for i := 1; i < n; i++ {
        maxF[i] = max(maxF[i-1]*nums[i], max(nums[i], minF[i-1]*nums[i]))
        minF[i] = min(minF[i-1]*nums[i], min(nums[i], maxF[i-1]*nums[i]))
    }
    
    ans := maxF[0]
    for i := 1; i < n; i++ {
        ans = max(ans, maxF[i])
    }
    
    return ans
}

时间和空间复杂度均为O(N),但是我们可以发现,maxF和minF中的每个数据都只是在计算后一个数据的时候才用到了一次,最后则是统计最大值,所以在这里我们可以进行优化,只需要在计算maxF和minF的时候直接计算ans即可,这样就可以将空间复杂度优化为O(1),代码如下:

func maxProduct(nums []int) int {
    maxF, minF, ans := nums[0], nums[0], nums[0]

    for i := 1; i < len(nums); i++ {
        mx, mn := maxF, minF
        maxF = max(mx * nums[i], max(nums[i], mn * nums[i]))
        minF = min(mn * nums[i], min(nums[i], mx * nums[i]))
        ans = max(maxF, ans)
    }

    return ans
}

结语

最近决定要稍微多写一点题解了,只要是第一次写错的,争取都写一遍吧, 欢迎交流学习


http://www.kler.cn/a/538886.html

相关文章:

  • PWM波形输出
  • 代码随想录day09
  • CMOS 图像传感器市场趋势和新兴应用
  • 现在中国三大运营商各自使用的哪些band频段
  • 树和二叉树_7
  • neo4j-解决导入数据后出现:Database ‘xxxx‘ is unavailable. Run :sysinfo for more info.
  • 【Android—OpenCV实战】实现霍夫圆检测针对沙盘交通灯信号检测
  • 电脑的睡眠有什么用?
  • Dcoker
  • 活动预告 |【Part1】Microsoft 安全在线技术公开课:安全性、合规性和身份基础知识
  • 基于SpringBoot和PostGIS的各省与地级市空间距离分析
  • docker grafana安装
  • 边缘计算网关驱动智慧煤矿智能升级——实时预警、低延时决策与数字孪生护航矿山安全高效运营
  • 【RabbitMQ】RabbitMQ的下载安装及使用
  • FaceFusion如何设置公开链接和端口
  • ASN.1 格式与Java类转换
  • 【自然语言处理】利用Memory Layer替换Transformer中的FFN
  • 缓存实战:Redis 与本地缓存
  • 黑马React保姆级(PPT+笔记)
  • 使用 Three.js 实现热力渐变效果
  • C++线程池
  • 如何设置爬虫的延时避免频繁请求?
  • 使用rustDesk搭建私有远程桌面
  • vue+element-ui简洁完美实现ju动漫网站
  • ASP.NET Core托管服务
  • Java 线程池内部任务出异常后,如何知道是哪个线程出了异常