首页 > 其他分享 >LeetCode 152 乘积最大子数组

LeetCode 152 乘积最大子数组

时间:2024-08-02 16:21:02浏览次数:13  
标签:152 乘积 nums int max min 数组 LeetCode dp

题目描述

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

思路

这一题用普通的连续子数组思路求解时有一个问题:子问题的最优解不一定是总体的最优局部解。也就是不满足最优子结构,例如:[-2,3,-4],这个用例中,[-2,3]的最大乘积是3,而不是-6,但是[-2,3,4]的最大乘积需要让-2和3相乘得到-6,然后-6再和-4相乘得到24。解决方式是再维护一个dp数组,也就是一共有两个dp数组,其中一个称为dp_max,另一个称为dp_min。

  • dp_max:dp_max[i]表示数组nums中以nums[i]结束的连续子数组的最大乘积。
  • dp_min:dp_min[i]表示数组nums中以nums[i]结束的连续子数组的最小乘积。

然后

  • 在求解dp_max数组的过程中,把dp_min[i-1] * nums[i]作为一个候选值
  • 在求解dp_min数组的过程中,把dp_max[i-1] * nums[i]作为一个候选值

具体步骤

1 确定dp数组的含义

  • dp_max:dp_max[i]表示数组nums中以nums[i]结束的连续子数组的最大乘积。
  • dp_min:dp_min[i]表示数组nums中以nums[i]结束的连续子数组的最小乘积。

2 确定状态转移方程

dp_max = MAX{nums[i], dp_max[i - 1] * nums[i], dp_min[i - 1] * nums[i]}
dp_min = MIN{nums[i], dp_min[i - 1] * nums[i], dp_max[i - 1] * nums[i]}

3 确定初始状态

初始状态就是dp_max[i] = nums[i], dp_min[i] = nums[i]

代码

class Solution {
    public int maxProduct(int[] nums) {
        int[] dp_max = new int[nums.length];
        int[] dp_min = new int[nums.length];
        System.arraycopy(nums, 0, dp_max, 0, nums.length);
        System.arraycopy(nums, 0, dp_min, 0, nums.length);
        for (int i = 1; i < nums.length; i++) {
            dp_max[i] = Math.max(Math.max(dp_max[i], dp_max[i - 1] * nums[i]), dp_min[i - 1] * nums[i]);
            dp_min[i] = Math.min(Math.min(dp_min[i], dp_min[i - 1] * nums[i]), dp_max[i - 1] * nums[i]);
        }
        int ans = Integer.MIN_VALUE;
        for (int i = 0; i < dp_max.length; i++) {
            ans = Math.max(ans, dp_max[i]);
        }
        return ans;
    }
}

标签:152,乘积,nums,int,max,min,数组,LeetCode,dp
From: https://www.cnblogs.com/zawaludo/p/18338994

相关文章

  • 【leetcode232:用栈实现队列】
    leetcode232:用栈实现队列题目:请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):实现MyQueue类:voidpush(intx)将元素x推到队列的末尾intpop()从队列的开头移除并返回元素intpeek()返回队列开头的元素booleanemp......
  • Oracle归档日志异常增长问题的排查过程 转载 : https://blog.csdn.net/3moods/article
    Oracle归档日志是Oracle数据库的重要功能,用于将数据库的重做日志文件(RedoLog)保存到归档日志文件(ArchiveLog)中。归档日志的作用是提供数据库的备份和恢复功能,以及支持数据库的持续性和数据完整性。当数据库处于归档模式时,数据库引擎会将已经写满的重做日志文件保存到归档日志文件......
  • LeetCode | 59 SpiralMatrixII
    主类https://github.com/dolphinmind/datastructure/tree/datastructure-array-02循环不变量原则,保证问题边界的逻辑一致性(从二分法的启发)初始位置旋转圈数奇偶性四条边的边界逻辑offsetpackagecom.github.dolphinmind.array;/***@authordolphinmind*@C......
  • [Leetcode]SQL语句
    groupby182.查找重复的电子邮箱SQLSchemaPandasSchema表:Person+-------------+---------+|ColumnName|Type|+-------------+---------+|id|int||email|varchar|+-------------+---------+id是该表的主键(具有唯一值的列)。此......
  • 二叉搜索树,Map,Set,LeetCode刷题
    二叉搜索树,Map,Set1.二叉搜索树2.二叉搜索树的模拟实现1.1插入操作1.2查找操作1.3删除操作3.二叉搜索树时间复杂度分析4.TreeMap和TreeSet5.Map5.1Map的常用方法5.2Map.Entry<K,V>6.Set6.1Set的常用方法LeetCode刷题1.二叉搜索树与双向链表1.二叉搜......
  • LeetCode | 209 MinimumSizeSubarraySum
    分析本题中是找与target相符的最小连续的子数组和,找一个能够容纳target这么大的最小子区间。虽然本节引入了滑动窗口的概念,可我更偏好于,这是一只毛毛虫在数组上的移动,找到最小的容纳自己位置的地方target可看作毛虫本身的重量,数组中的每个元素值表示可承受的重量,right右指针看......
  • LeetCode 322 零钱兑换
    题目描述给你一个整数数组coins,表示不同面额的硬币;以及一个整数amount,表示总金额。计算并返回可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回-1。你可以认为每种硬币的数量是无限的。思路这是一个完全背包问题,背包问题当满足:物品不......
  • 每日一题:Leetcode-48 旋转图像
    力扣题目解题思路java代码力扣题目:给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转90度。你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。示例1:输入:matrix=[[1,2,3],[4,5,6]......
  • LeetCode 2024/8 每日一题合集
    2024-7-1LCP40.心算挑战代码实现classSolution{public:intmaxmiumScore(vector<int>&cards,intcnt){intn=size(cards);std::sort(cards.rbegin(),cards.rend());intsum=std::accumulate(cards.begin(),cards.begin()......
  • 两数之和(LeetCode题)
    题目:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。示例1:输入:nums=......