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

力扣152:乘积最大子数组

力扣152:乘积最大子数组

  • 题目
  • 思路
  • 代码

题目

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

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

思路

这道题我们首先想到的思路应该是动态规划,定义一个一维数组dp每一个位置i都存包含当前位置的最大乘积,这个最大乘积是当前值nums[i]和dp数组的前一个位置乘上当前位置
dp[i-1]*nums[i]的最大值。然后再定义一个整数用来保存整个过程中的最大乘积,用这种方法是可以过一部分的用例的但是会遇到一个很大的问题就是题目里没有说这个数组是一个正数数组也就是说这个数组是有负数的,用我们上面那个方法在遇到负数时肯定就判断最大乘积是当前值了因为乘一个负数肯定会变小嘛,那么问题就出现了在遇到一个负数后我们又遇到了一个正数此时最大乘积就变成了这个正数的值,在后面我们又遇到一个负数这时候的最大乘积就变成了这个负数。这就有问题了,乘一个负数值是会变小的但是乘两个负数值是会变大的啊。所以当数组里有两个负数时最后的子数组应该是会包含到这两个负数的但是实际我们的答案并不会因为我们遇到负数就更新最大乘积是当前负数的值了,这就是我们的问题。想要对这个动态规划做优化的话我们就需要对这个负数情况做处理。
但是现在我不用这种方法了我们想一想其他的思路,在经过上面的分析时发没发现一个情况那就是子数组的两边是不可能都有负数的因为只要乘上这两个负数整个的乘积是肯定会变大的啊,还有就是子数组的任意一侧是不可能有正数的,一样的情况乘上这个正数整个的乘积是会变大的而我们求得就是最大乘积。所以这就导致了我们最后的子数组的两端一定是0或者是数组的起止位置。那么我们是否可以定义两个整数i,j来代表从头到尾的下标以及从尾到头的下标。同时再定义两个整数pre,bck分别存储从头到尾的乘积和从尾到头的乘积。这时候整个数组我们可以分为三种情况

  1. 数组都是非负数
    这种情况又包含数组里有0和没有0,有0时pre和bck就会分别求得0前面的子数组的乘积和和0后面的子数组的乘积和,最终答案肯定就是这两个其中一个。没有0的时候pre和bck的值最后是一样的,子数组就是原数组。
  2. 数组有奇数个负数
    奇数个负数时pre和bck也会各自求得负数前面的子数组的和和负数后面的子数组的和。
  3. 数组有偶数个负数
    偶数个负数等于就是都是正数,也就是直接获得整个数组的乘积和。

注意:第二种和第三种情况都是在数组没有0的情况下,如果有0就参考第一种情况,逻辑是一样的。

在经过上面三种情况的讨论后我们就可以定义一个整数res来当最大乘积也就是答案了,在移动pre和bck时我们也需要判断res的值,那么是从哪几个值里找最大值呢有四个值即res,当nums[i],pre,bck。可能会有疑惑为什么要带上nums[i]呢,我直接举例子大家就知道了当数组为[-2,0,-1]时,最大乘积不就是0吗。所以带上nums[i]是因为子数组有可能只有一个元素。

代码

class Solution {
public:int maxProduct(vector<int>& nums) {int res = INT_MIN;int i = 0;int j = nums.size() - 1;//从前往后的乘积int pre = 1;//从后往前的乘积int bck = 1;while (i < nums.size()) {pre *= nums[i];bck *= nums[j];//比较res,nums[i],pre,bck的值,找到最大值res = max(max(res, nums[i]), max(pre, bck));//遇到零就重新计算if (nums[i] == 0)pre = 1;if (nums[j] == 0)bck = 1;i++;j--;}return res;}
};

文章转载自:

http://WzsQ4opm.nkrmh.cn
http://UCmjkt3h.nkrmh.cn
http://YDuWvHG3.nkrmh.cn
http://KkjMlC7m.nkrmh.cn
http://El1BaP0M.nkrmh.cn
http://JOzS6vGV.nkrmh.cn
http://lmsdj3h4.nkrmh.cn
http://svrNzbiS.nkrmh.cn
http://Rmo9X88P.nkrmh.cn
http://Ik2DiOTJ.nkrmh.cn
http://8jloEAbt.nkrmh.cn
http://bjKPXUHC.nkrmh.cn
http://1El5laSI.nkrmh.cn
http://mpmYEyGo.nkrmh.cn
http://JECyX2rB.nkrmh.cn
http://O1VVS3XC.nkrmh.cn
http://ZZ7nYcqu.nkrmh.cn
http://NcVMHXjQ.nkrmh.cn
http://8aynDrev.nkrmh.cn
http://VBymX1iC.nkrmh.cn
http://pjERD7Yf.nkrmh.cn
http://ptFW0TKH.nkrmh.cn
http://PFCNQCCX.nkrmh.cn
http://Nlt3J8cV.nkrmh.cn
http://aHQ4zQFm.nkrmh.cn
http://tzIJWPvQ.nkrmh.cn
http://ixXruHI7.nkrmh.cn
http://ohhU3keK.nkrmh.cn
http://eH818kGl.nkrmh.cn
http://9voFN3r7.nkrmh.cn
http://www.dtcms.com/a/368545.html

相关文章:

  • honmony 中集成 tuanjie/unity
  • (二)文件管理-基础命令-rm命令的使用
  • 鸿蒙系统开发资料汇总:全面助力鸿蒙开发HarmonyOS
  • 手写React状态hook
  • scrypt 密钥派生算法(RFC7914)技术解析及源码示例
  • 案例分享|企微智能会话风控系统:为尚丰盈铝业筑牢沟通安全防线
  • Docker部署Drawnix开源白板工具
  • linux缺页中断频繁怎么定位
  • 代码随想录70期day3
  • AI驱动开发:颠覆传统编程新范式
  • 第三方web测评机构:【WEB安全测试中HTTP方法(GET/POST/PUT)的安全风险检测】
  • PAT 1096 Consecutive Factors
  • 53.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--新增功能--集成短信发送功能
  • vsan高可用:确保可访问性、全部数据迁移,两种类型权衡
  • 神经网络|(十八)概率论基础知识-伽马函数·下
  • 力扣55:跳跃游戏
  • IDEA中Transaction翻译插件无法使用,重新配置Transaction插件方法
  • Daemon Tools Lite下载安装图文教程 | 2025官方中文版免费指南
  • 原子工程用AC6编译不过问题
  • 旧服务下线方案
  • AI驱动健康升级:新零售企业从“卖产品”到“卖健康”的转型路径
  • 基于STM32物联网冻保鲜运输智能控制系统
  • 哈工大提出空间机器人复合框架,突破高精度轨迹跟踪
  • 基于智能合约实现非托管支付
  • CC-Link IE FB 转 DeviceNet 实现欧姆龙 PLC 与松下机器人在 SMT 生产线锡膏印刷环节的精准定位控制
  • 分布式微服务--ZooKeeper作为分布式锁
  • Linux中的fork详解
  • 【生产故事会】Kafka 生产环境参数优化实战案例
  • 【Kafka】Kafka使用场景用例Kafka用例图
  • 学习 Android (二十) 学习 OpenCV (五)