这是我参与更文挑战的第15天,活动详情查看: 更文挑战
什么题可以选择动态规划来做?
1.计数
- 有多少种方式走到右下角
- 有多少种方法选出k个数是的和是sum
2.求最大值最小值
- 从左上角走到右下角路径的最大数字和
- 最长上升子序列长度
3.求存在性
- 取石子游戏,先手是否必胜
- 能不能选出k个数使得和是sum
4.综合运用
- 动态规划 + hash
- 动态规划 + 递归
- ...
leecode 152. 乘积最大子数组
给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
示例 1:
输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
示例 2:
输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
--
❤️❤️❤️❤️
2.1. 动态规划组成部分1:确定状态
简单的说,解动态规划的时候需要开一个数组,数组的每个元素f[i]或者f[i][j]代表什么,类似数学题中x, y, z代表什么
最后一步
这种题的话,我们可以定义一个最大值max为乘积最大子数组
因为涉及到负数,避免出现第一次负数,但第二次乘积是正数,我们还需要一个min为乘积最小子数组。
当然还需要一个变量,来记录乘积最大子数组ans
依次计算就行了。
1.2. 动态规划组成部分2:转移方程
简单的说:你需要记录
之前的乘积maxcurr,当前值curr和mincurr 的最大值
之前的乘积mincurr,当前值curr,和maxcurr 的最小值
1.3. 动态规划组成部分3:初始条件和边界情况
int max = nums[0], min = nums[0], ans = nums[0];
获取第一个值
1.4. 动态规划组成部分4:计算顺序
依次计算
参考代码
GO语言版
func maxProduct(nums []int) int {
maxF, minF, ans := nums[0], nums[0], nums[0]
for i := 1; i < len(nums); i++ {
mx, mn := maxF, 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
}
func max(x, y int) int {
if x > y {
return x
}
return y
}
func min(x, y int) int {
if x < y {
return x
}
return y
}
java版
class Solution {
public int maxProduct(int[] nums) {
int maxF = nums[0], minF = nums[0], ans = nums[0];
int length = nums.length;
for (int i = 1; i < length; ++i) {
int mx = maxF, mn = minF;
maxF = Math.max(mx * nums[i], Math.max(nums[i], mn * nums[i]));
minF = Math.min(mn * nums[i], Math.min(nums[i], mx * nums[i]));
ans = Math.max(maxF, ans);
}
return ans;
}
}
❤️❤️❤️❤️
非常感谢人才们能看到这里,如果这个文章写得还不错,觉得有点东西的话 求点赞👍 求关注❤️ 求分享👥 对帅气欧巴的我来说真的 非常有用!!!
如果本篇博客有任何错误,请批评指教,不胜感激 !
文末福利,最近整理一份面试资料《Java面试通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:GitHub github.com/Tingyu-Note…,更多内容关注公号:汀雨笔记,陆续奉上。