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

【Leetcode152】乘积最大子数组(动态规划)

文章目录

  • 一、题目
  • 二、思路
  • 三、代码

一、题目

在这里插入图片描述

二、思路

(0)读懂题意:题目的“连续”是指位置的连续,而不是说数字的连续,这是个大坑。

(1)确定状态:定义两个状态来记录当前子数组的最大乘积、最小乘积。因为在处理负数时,最小乘积乘以负数可能变为最大乘积。dp_max[i]表示以nums[i]结尾的子数组的最大乘积、dp_min[i]表示以nums[i]结尾的子数组的最小乘积。

(2)状态转移方程:对于每个元素nums[i],我们的dp_max[i]dp_min[i]可以从这三个数中确定:

  • 只包含当前元素 nums[i]
  • 当前元素与之前的最大乘积子数组乘积,即 dp_max[i-1] * nums[i]
  • 当前元素与之前的最小乘积子数组乘积,即 dp_min[i-1] * nums[i]

即状态转移方程可表示为:

dp_max[i] = max(nums[i], dp_max[i-1] * nums[i], dp_min[i-1] * nums[i])
dp_min[i] = min(nums[i], dp_max[i-1] * nums[i], dp_min[i-1] * nums[i])

(3)初始状态+边界条件:以第一个元素结尾的子数组最大乘积就是它本身、以第一个元素结尾的子数组最小乘积就是它本身、初始乘积最大结果为第一个元素。

(4)遍历顺序:从左到右遍历数组。

三、代码

(方法一)按照思路的代码如下,时间复杂度为O(n),空间复杂度为O(n)。

class Solution(object):def maxProduct(self, nums):""":type nums: List[int]:rtype: int"""if len(nums) == 0:return 0if len(nums) == 1:return nums[0]# 初始化数组n = len(nums)dp_max = [0] * n dp_min = [0] * n# 初始状态dp_max[0] = nums[0]dp_min[0] = nums[0]cheng_ans = nums[0]# 从第二个元素开始遍历for i in range(1, n):num = nums[i]dp_max[i] = max(num, dp_max[i-1]*num, dp_min[i-1]*num)dp_min[i] = min(num, dp_max[i-1]*num, dp_min[i-1]*num)cheng_ans = max(cheng_ans, dp_max[i])return cheng_ans

(方法二)为了优化空间复杂度,发现每次当前只利用前一次状态,所以dp_maxdp_min没必要单独用两个数组记录所有的状态。但注意在计算状态转移方程时,分别计算dp_max和dp_min都会用到上一次的dp_max和dp_min,这为了用错dp_mxn,可以直接对num确保是正数后,交换dp_max和dp_min的位置,减少max和min函数的入参个数。

class Solution(object):def maxProduct(self, nums):""":type nums: List[int]:rtype: int"""if len(nums) == 0:return 0if len(nums) == 1:return nums[0]# 初始化数组n = len(nums)# 初始状态dp_max = nums[0]dp_min = nums[0]cheng_ans = nums[0]# 从第二个元素开始遍历for i in range(1, n):num = nums[i]if num < 0:dp_max, dp_min = dp_min, dp_maxdp_max = max(num, dp_max*num)dp_min = min(num, dp_min*num)cheng_ans = max(cheng_ans, dp_max)return cheng_ans
http://www.lryc.cn/news/433387.html

相关文章:

  • STM32(十二):DMA直接存储器存取
  • 关于我2020年7月至今(2024.9)的“炒股”经历和感受
  • 【Tools】Prompt Engineering简介
  • 多路转接之select(fd_set介绍,参数详细介绍),实现非阻塞式网络通信
  • 乐鑫安全制造全流程
  • 〖open-mmlab: MMDetection〗解析文件:configs/_base_/schedules
  • Android之Handler是如何保证延迟发送的
  • 定位信标、基站、标签,定位信标是什么
  • 2024国赛数学建模B题完整分析参考论文38页(含模型和可运行代码)
  • Hive是什么?
  • 计算机网络:http协议
  • 【stata】自写命令分享dynamic_est,一键生成dynamic effect
  • 文心一言 VS 讯飞星火 VS chatgpt (342)-- 算法导论23.2 1题
  • 部署若依Spring boot项目
  • oc打包:权限弹窗无法正常弹出
  • 深入理解RxJava:响应式编程的现代方式
  • Maven 依赖漏洞扫描检查插件 dependency-check-maven 的使用
  • 2. 下载rknn-toolkit2项目
  • xhr、ajax、axois、fetch的区别
  • 【HuggingFace Transformers】OpenAIGPTModel源码解析
  • macOS安装Java和Maven
  • SpringBoot教程(安装篇) | Elasticsearch的安装
  • 前端登录鉴权——以若依Ruoyi前后端分离项目为例解读
  • 【Tools】大模型中的自注意力机制
  • PhotoZoom Classic 9软件新功能特性及安装激活图文教程
  • 【数据结构】直接插入排序
  • JavaScript 实现虚拟滚动技术
  • 【重学 MySQL】十八、逻辑运算符的使用
  • 关于 QImage原始数据格式与cv::Mat原始数据进行手码数据转换 的解决方法
  • 前端WebSocket客户端实现