leetcode 152:最大乘积子数组

LeetCode 152. 乘积最大子数组【c++/java详细题解】 目录1、题目2、思路:3、c++代码4、java代码 1、题目 给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。 示例 1: 输入: [2,3,-2,4] 输出: 6 解释: 子数组 [2,3] 有最大乘积 6。 示例 2: 输入: [-2,0,-1] 输出: 0 解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。 2、思路: (动态规划) O(n)O(n)O(n) 给你一个整数数组 nums ,让我们找出数组中乘积 阅读详情

题目描述:
给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
测试用例的答案是一个 32-位 整数。
子数组 是数组的连续子序列。
示例1:
输入: nums = [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
示例2:
输入: nums = [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
思路1:
通过递归进行暴力求解,每个元素有选和不选两种情况,保存乘积的最大值,时间复杂度为O(2^n)。
思路2:
动态规划DP

  1. 状态的定义:dp[i][2] i->包含第i个元素的子序列
    定义成二维状态的原因:因为元素可能出现负数的情况,所以需要保留正的最大值和负的最小值,然后根据nums[i]的正负得到最后的结果。
    [i][0] 正的最大值; [i][1]负的最小值
  2. 状态转移方程:
dp[i][0] = 
	if nums[i]>0:
		dp[i-1][0] * nums[i]
	else:
		dp[i-1][1]*nums[i]
dp[i][1] = 
	if nums[i] >0:
		dp[i-1][[1] *a[i]
	else:
		dp[i-1][0] * a[i]

具体在操作的时候,还要注意到dp[i-1][0]和dp[i-1][1]的正负,详见代码。

class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        # 注意一下申请数组怎么做
        dp = [[]]
        for h in range(len(nums)):
            dp.append([])
            for l in range(2):
                dp[h].append([])
        max = nums[0]
        # 初始化
        if nums[0] >= 0:
            dp[0][0] = nums[0]
            dp[0][1] = 0
        else:
            dp[0][0] = nums[0]
            dp[0][1] = nums[0]
        for i in range(1, len(nums)):
            if nums[i] >= 0:
                if dp[i-1][0] > 0:
                    dp[i][0] = dp[i-1][0] * nums[i]
                else:
                    dp[i][0] = nums[i]
                if dp[i-1][1] < 0:
                    dp[i][1] = dp[i-1][1] * nums[i]
                else:
                    dp[i][1] = 0
            else:
                if dp[i-1][1] < 0:
                    dp[i][0] = dp[i-1][1] * nums[i]
                else:
                    dp[i][0] = nums[i]
                if dp[i-1][0] > 0:
                    dp[i][1] = dp[i-1][0] * nums[i]
                else:
                    dp[i][1] = nums[i]
            if dp[i][0] > max:
                max = dp[i][0]
        return max

这样写的代码显得有一些冗余,参考题解得到的一个类似的思路:
在这里插入图片描述

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        vector <int> maxF(nums), minF(nums);
        for (int i = 1; i < nums.size(); ++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]));
        }
        return *max_element(maxF.begin(), maxF.end());
    }
};

进一步优化空间复杂度:

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        int maxF = nums[0], minF = nums[0], ans = nums[0];
        for (int i = 1; i < nums.size(); ++i) {
            int mx = maxF, mn = 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;
    }
};

用ans存最大值,避免过程中的存储消耗空间。

LeetCode 152. 乘积最大子数组:从暴力到双状态DP的清晰演进(C++/Java实现) 本文详细解析了LeetCode 152题“乘积最大子数组”的解题思路,从直观的暴力枚举法入手,揭示了传统单状态动态规划在负数处理上的陷阱,并重点阐述了双状态动态规划这一核心解法。通过同时维护以每个位置结尾的最大和最小乘积,有效处理了乘积的符号翻转问题,并提供了C++和Java两种语言的优化实现代码。 阅读详情

相关推荐

【中等】力扣算法题解析LeetCode152:乘积最大子数组

本文介绍了如何高效解决寻找数组中乘积最大的非空连续子数组问题。通过动态维护当前子数组的最大和最小乘积(处理负数情况),算法在O(n)时间内完成计算。Java代码展示了具体实现,包括初始化变量、遍历更新极值以及返回全局最大值。该方法适用于正数、负数和零的情况,确保结果正确且高效。

ylumwd的博客 565

LeetCode 之 乘积最大子数组

乘积最大子数组1. 暴力遍历2. 动态规划2.1 定义子问题2.2 状态转移方程2.3 返回最值2.4 报错解决3. 空间优化参考链接 题目要求找出数组 nums 中乘积最大的连续子数组,最直接的办法是遍历整个数组,穷举以数组元素 nums[i] 为开头的所有连续子数组,通过比较所有连续子数组的乘积,找到最大值,并返回。 可是穷举所有子数组的乘积的过程中,存在很多重复计算。因此可以考虑使用动态规划的思想来优化算法。 知识点: 动态规划及其空间优化 1. 暴力遍历 这种方法通过穷举所有可能的结果,得到最大值

qq_39220334的博客 1781

leetcode:152. 乘积最大子数组

连续乘积的最大子数组,如果借鉴最大子数组和的思路做是有问题,因为乘积涉及到正负问题,负负得正。两个大的负数相乘得到的值可能大于当前的正数。因此这里需要保留每个状态下的最大值和最小值。min_dp[i]表示以i结尾的时候的最小连续乘积,max_dp[i]表示以i结尾的时候的最大连续乘积;

uncle_ll的博客 409

每日一道算法题:乘积最大子数组

子数组是指在一个数组中,从某一个元素开始,到另一元素结束,所有元素按照顺序排列的一段序列。比如:在数组[1,2,3,4,5]中,子数组[2,3]就是从数组中第二个元素开始,到第三个元素结束的一段序列。最大子数组是指在一个数组中,累加和最大的一个子数组。比如:在数组[-2, 1, -3, 4, -1, 2, 1, -5, 4]中,最大子数组是[4,-1,2,1],其累加和为6。乘积最大子数组算法是机器学习特征选择中重要的数值型特征选择方法之一,在实际应用中具有广泛的应用。

weixin_44251099的博客 608

AI开发助手介绍

AI开发助手介绍随着NLP方向发展越来越成熟,AI写代码领域出现了几个非常好的模型,今天笔者给大家推荐几个AI Coding 助手AI Coding助手是以IDEA插件或vim插件形式提供服务,在编辑器中写代码时,可以实时预测下一行要输入的代码,提升开发效率。Github Copilot首先要介绍的是Github Copilot,Copilot是个AI Coding助手,它从注释和代码中提取上下文,给出单行和整个函数的代码建议,Copilot由Open AI 的CodeX模型提供支持,它是一个由OpenAI

bobo_simpler的博客 5765

嵌入式调光控制库:轻量级软启/渐变/记忆逻辑实现

调光控制是智能照明系统的核心基础功能,涉及亮度调节、人机交互与电气安全多重需求。其底层原理依赖于对相位角或PWM占空比的精确时序控制,并需融合软启动、渐变过渡、状态记忆等工程化逻辑。这类轻量级调光行为逻辑层,不直接操作硬件寄存器,而是以确定性、无动态内存、可配置的方式封装用户意图到目标亮度值(0–100%)的映射过程,显著提升产品鲁棒性与跨平台复用能力。广泛应用于TRIAC交流调光、LED直流PWM驱动及DALI/Matter等智能照明协议网关中,尤其适合资源受限的Cortex-M系列MCU和FreeRTO

weixin_28949937的博客 579

动态规划-乘积最大子数组

与最大乘积类似,最小乘积的更新也考虑了当前元素、前一个位置的最小乘积乘以当前元素,以及前一个位置的最大乘积乘以当前元素(当当前元素为负数时)。这是因为,负数乘以正数(前一个位置的最大乘积)会得到一个更小的负数,这可能是新的最小乘积。给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续 子数组 (该子数组中至少包含一个数字),并返回该子数组所对应的乘积。本身(如果前面的元素都是负数或者乘积小于当前元素),要么是前面位置的最大乘积。数组中的最大值即为所求的最大乘积子数组的乘积。

2302_80190174的博客 869

数据库迁移策略实战:MySQL到PostgreSQL

数据库迁移是一项复杂且细致的任务,需要充分的准备工作、合适的迁移策略和严格的验证与优化步骤。通过选择合适的迁移工具、进行手动迁移和应用程序适配、以及迁移后的验证与优化,可以确保数据迁移的成功和业务的连续性。希望本文的分享能够为大家在MySQL到PostgreSQL的数据库迁移实战中提供一些有用的参考和启示。

shejizuopin的博客 1732

乘积最大子数组

一、前言 回顾前文《最大子数组》,求解的是最高点到最低点差值,后经转换为累加和最大的子数组。对这个问题再扩展一下,将加给为乘,连续乘积最大的数组怎样求解呢? 《最大子数组》https://blog.youkuaiyun.com/nie2314550441/article/details/106036517 二、题目 给你一个整数数组 nums,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。 示例 1: 输入: [2,3,-2,4] 输出: 6 解释..

行走 506

【低空经济】低空无人驾驶航空器运行管理系统设计方案

低空无人驾驶航空器运行管理系统(以下简称“系统”)旨在为低空域内的无人驾驶航空器(UAV)提供高效、安全、智能的运行管理服务。系统通过集成先进的通信、导航、监控、数据处理和人工智能技术,实现对低空域内无人驾驶航空器的实时监控、动态调度、风险评估和应急响应,确保其在复杂空域环境中的安全运行。系统的核心功能包括空域管理、飞行计划审批、实时监控、冲突预警、应急管理和数据分析。空域管理模块负责划分和管理低空域资源,确保不同飞行任务之间的空域隔离和高效利用。

2502_92579126的博客 1140

A-Frame引擎开发:A-Frame基础入门_(11).A-Frame物理引擎集成

在上一节中,我们学习了如何在A-Frame中创建基本的3D场景和交互元素。然而,为了使虚拟现实游戏更具真实感和互动性,物理引擎的集成是必不可少的。物理引擎可以模拟现实世界中的物理行为,如重力、碰撞、摩擦等,从而增强用户的沉浸感。物理引擎在虚拟现实游戏中的重要性不言而喻。它不仅能够模拟物体的运动和相互作用,还能为游戏提供更真实的反馈和体验。例如,当玩家在虚拟世界中推动一个物体时,物理引擎可以确保物体按照预期的方式移动,而不是简单地穿墙而过或突然消失。重力是物理引擎中最基本的特性之一。在A-Frame中,我们可

chenlz2007的博客 797

力扣(LeetCode)刷题第152题:乘积最大子数组

文章目录前言一、分析题目二、解题思路1.找出DP状态2.找出DP状态转移方程3.代码部分三、总结 前言 题目地址:乘积最大子数组 一、分析题目 给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。。 示例 1: 输入: [2,3,-2,4] 输出: 6 解释: 子数组 [2,3] 有最大乘积 6。 示例 2: 输入: [-2,0,-1] 输出: 0 解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。 我觉得你如果做的多了

代码届的小白的博客 1040

【小白深度教程 1.3】使用 BP-Net 深度补全网络,进行 KITTI 稠密点云和图像融合(Depth Completion 实战)

在上一节中,我们展示了如何将从激光雷达获取的稀疏点云(深度)映射到图像。因此这篇论文我们尝试使用 Depth Completion(深度补全)技术,来将稀释的点云深度,补全为稠密深度。

2401_87064292的博客 1199

LeetCode_152: 乘积最大子数组

链接 LeetCode_152: 乘积最大子数组 问题 给你一个整数数组nums,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。 示例 1: 输入: [2,3,-2,4] 输出: 6 解释:子数组 [2,3] 有最大乘积 6。 示例 2: 输入: [-2,0,-1] 输出: 0 解释:结果不能为 2, 因为 [-2,-1] 不是子数组。 题解 题解1: 动态规划 思路: 第i个元素的最优解并不是在第i个元素的最优解基础上实现的;...

AN_ERA的博客 259

华为OD机试双机位C卷:日志排序 (Py/C/C++/Java/Js/Go)

华为OD机试双机C卷真题【日志排序】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。华为OD机试-日志排序。

qq_45776114的博客 1754

RK3588, FFmpeg 拉流 RTSP, mpp 硬解码转RGB

RK3588, FFmpeg 拉流 RTSP, mpp 硬解码转RGB

J。 2340

力扣152:乘积最大子数组

本文介绍了力扣152题"乘积最大子数组"的解法。该题要求找出数组中乘积最大的非空连续子数组。文章首先分析了一种基于动态规划的初步思路,指出其在处理负数时会失效的问题。随后提出更优的双向遍历解法:通过同时计算从头到尾和从尾到头的乘积,分别处理全正数、奇数个负数和偶数个负数三种情况,并特别处理0值的情况。最终代码实现中,维护两个乘积变量pre和bck,在遍历过程中比较当前值、pre和bck,同时遇到0时重置乘积,从而保证能够正确找到最大乘积。这种方法有效解决了负数乘积反转的问题,时间复杂度为

weixin_74285822的博客 773

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

leetcode:152. 乘积最大子数组

代码】leetcode152.乘积最大子数组。

OceanStar的博客 332

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Leetcode152:乘积最大子数组

文章目录题目描述思路分析代码实现 题目描述 思路分析 换种思路去想,如果数组全是正数,那么最大值就是数组中所有值得乘积。如果数组中有负数,那么只要保证子数组中含有偶数个负数就可以实现最大值。注意:还要考虑子数组中可能含有0,如果在遍历时遇到0,就将max值置为1,进行下一次的最大值求解。 代码实现 public int maxProduct(int[] nums) { if (nums.length == 0) { return 0; } int max = 1; int re

sparky的博客 372

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

面试官最爱问的LeetCode 152:乘积最大子数组的三种解法与避坑指南

本文深入解析LeetCode 152题'乘积最大子数组'的三种解法,包括动态规划标准解法、暴力法优化及前缀积解法,并揭示面试中常见的理解误区。特别强调处理负数和零值的技巧,提供代码模板和应答策略,帮助读者在技术面试中从容应对这一经典动态规划问题。

weixin_42523792的博客 331

leetcode-152:乘积最大子数组

给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。测试用例的答案是一个 32-位 整数。子数组 是数组的连续子序列。

菊头蝙蝠的博客 139

LeetCode第 152 题:乘积最大子数组(C++)

152. 乘积最大子数组 - 力扣(LeetCode) 要求是连续的子数组,动态规划但是要考虑负数的情况: 乘积最大子数组 - 乘积最大子数组 - 力扣(LeetCode) class Solution { public: int maxProduct(vector<int>& nums) { int n = nums.size(); vector<int> maxf(nums), minf(nums); for(int

zj 654

菜鸟刷LeetCode-C语言实现:152.乘积最大子数组

刷LeetCode纯粹是因为无聊,在乏味的生活中找一点有趣的事情做 作为一个接触LeetCode不久的大一非计算机专业的学生,我写下这篇博客只是为了记录自己的学习过程,强化一下记忆并且督促自己不断学习。 先看一下原题: 152.乘积最大子数组 给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。 示例 1: 输入: [2,3,-2,4] 输出: 6 解释: 子数组 [2,3] 有最大乘积 6。 示例 2: 输入: [-2,0,-1] 输

ymliu_sjtu的博客 417

LeetCode: 152. 乘积最大子数组

给你一个整数数组 nums,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字)。 示例 1: 输入: [2,3,-2,4] 输出: 6 解释:子数组 [2,3] 有最大乘积 6。 示例 2: 输入: [-2,0,-1] 输出: 0 解释:结果不能为 2, 因为 [-2,-1] 不是子数组。 分析: 我们尝试用动态规划来解决这个问题,设立一个数组,d...

LightInDarkness的博客 303

LeetCode 152. 乘积最大子数组:从暴力到DP的双状态优化详解(C++/Java)

本文详细解析了LeetCode 152题“乘积最大子数组”的解题思路。针对数组中存在负数和零导致乘积符号翻转的难点,文章重点阐述了从暴力枚举到动态规划的优化过程,并深入讲解了核心的“双状态DP”解法。该方法通过同时维护以当前元素结尾的最大乘积和最小乘积,有效处理了符号问题,并提供了C++和Java两种语言的代码实现与空间优化技巧。

weixin_29204749的博客 218

LeetCode第152题:乘积最大子数组(中等)

LeetCode第152题:乘积最大子数组(中等) 题目:给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。 解题思路:仿照之前的题,终于学会了前缀做法。 class Solution { public int maxProduct(int[] nums) { int len = nums.length; int ans = nums[0]; //计算前缀积

new_whiter的博客 399
上一篇: 动态规划-股票系列问题
下一篇: leetcode 121、122、123、188、309、714 买卖股票的最佳时机
coding_diamond
博客等级 码龄8年 8粉丝 131原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值