携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情
前言
- leetcode hot100,是大厂面试高频题,也是必刷算法题。精选了100道LeetCode上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,按照官方说的,熟练掌握这 100 道题,就具备了代码世界通行的基本能力。
leetcode152题(# 乘积最大子数组)
本文来讲hot100第152题(乘积最大子数组),本题是比较简单且典型的动态规划的题目,可以当做动态规划的练手题目.
给你一个整数数组 nums
,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
测试用例的答案是一个 32-位 整数。
子数组 是数组的连续子序列。
示例:
输入: nums = [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
输入: nums = [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
提示:
1 <= nums.length <= 2 * 104
-10 <= nums[i] <= 10
nums
的任何前缀或后缀的乘积都 保证 是一个 32-位 整数
分析
- 乘积最大的非空连续子数组,子数字的长度是[1,nums.length]位
- 返回该子数组的乘积
- 如果子数组中包含0,则结果也是0
思路
- 使用动态规划来解决此题
- 先明确dp的定义
- dp[n] 表示 n 个元素里面,出现连续元素相乘的最大乘积。
- 因为单个数字也算子数组,所以我们dp可以初始化,0为第一个数组
- 2个负数会让乘积为正数,存储上次乘积的结果 dp[n-1] 的最大值和最小值。
- dp 方程 dp[n] = Math.max(dp[n-1]*nums[n], nums[n])
- 使用max与min来临时存储
代码
let max = (min = nums[0]),
dp = [nums[0]];
for (let i = 1; i < nums.length; i++) {
if (nums[i] < 0) {
[max, min] = [min, max];
}
max = Math.max(max * nums[i], nums[i]);
min = Math.min(min * nums[i], nums[i]);
dp[i] = max;
}
return Math.max(...dp);