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

力扣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://www.xdnf.cn/news/20288.html

相关文章:

  • 智慧养老综合实训室建设方案:依托教育革新提升养老人才科技应用能力
  • nestjs 缓存配置及防抖拦截器
  • C# 阿里云 OSS 图片上传步骤及浏览器查看方法
  • 深入解析汇编语言的奥秘
  • 文件不展示Eslint的报错红色
  • 前端三件套+springboot后端连通尝试
  • 系统学习算法 专题十八 队列+宽搜
  • Doris 数据仓库例子
  • OpenCV C++ 色彩空间详解:转换、应用与 LUT 技术
  • 一文详解深度学习中神经网络的各层结构与功能!
  • SQL-DML
  • 计算机网络4 第四章 网络层——网络间的通信问题(省际之间如何规划信件运输路线)
  • 酒店实习生转正信息调整编程实现(Python字典应用基础题)
  • 【yolo】YOLOv8 训练模型参数与多机环境差异总结
  • Kafka面试精讲 Day 8:日志清理与数据保留策略
  • Grafana 导入仪表盘失败:从日志排查到解决 max\_allowed\_packet 问题
  • 汽车软件研发智能化:AI在CI/CD中的实践
  • 实践指南:利用衡石AI Data Agent实现自然语言驱动的指标开发与归因
  • 【最新版】发烧级完美解码播放器PureCodec v2025.08.29 中文免费版_电脑播放器影音解码包
  • 基于51单片机WIFI智能家居系统设计
  • 相机刮除拜尔阵列
  • 使用海康机器人相机SDK实现基本参数配置(C语言示例)
  • Linux查看相机支持帧率和格式
  • Linux系统安全加固:构建云计算安全的第一道防线
  • 迁移学习-ResNet
  • VBA 中使用 ADODB 操作 SQLite 插入中文乱码问题
  • JVM新生代和老生代比例如何设置?
  • Vue 3 项目中引入 Iconify
  • Spring Boot 和 Spring Cloud: 区别与联系
  • Oracle到ClickHouse:异构数据库ETL的坑与解法