动态编程 - 子阵列系列 - 最大子阵列和
最编程
2024-10-19 07:12:29
...
1.题目解析
题目来源:53.最大子数组和——力扣
测试用例
2.算法原理
1.状态表示
dp[i]:以第i个位置为结尾的数组所有子数组之和的最大值
2.状态转移方程
此时对dp[i]的填值有两种情况
1.以当前位置本身的数为子数组,则子数组之和就是该数
2.以当前位置之前的所有数为子数组但不包括当前数,求出前面子数组的总和
对于dp[i]来说需要取二者的较大值
3.初始化
由于填表时需要使用到前一个数,所以需要初始化第一个数,但是可以设置虚拟位置来简单化,虚拟位置的值置为0避免影响后续的填表
4.填表顺序
从左到右
5.返回值
返回dp表中最大的值即可
3.实战代码
class Solution {
public:
int maxSubArray(vector<int>& nums)
{
int n = nums.size();
vector<int> dp(n+1);
dp[0] = 0;
int ret = INT_MIN;
for(int i = 1;i <= n;i++)
{
dp[i] = max(nums[i-1],dp[i-1] + nums[i-1]);
ret = max(ret,dp[i]);
}
return ret;
}
};
推荐阅读
-
动态编程 - 子阵列系列 - 最大子阵列和
-
连续子阵列最大累积乘法的动态编程解决方案详解
-
动态规划算法的两种经典解决方式:最优子结构和DP数组的使用解析-动态规划算法问题 什么叫作最优子结构? 和动态规划有什么关系? 为什么动态规划遍历DP数组的方式有正着遍历,有倒着遍历,有斜着遍历? 最优子结构 最优子结构是某些问题的一种特定的性质,并不是动态规划问题所特有的. 很多问题都具有最优子结构,但是其中大部分不具有重叠子问题,所以不会归为动态规划系列的问题 最优子结构: 可以从子问题的最优结果推导出更大规模问题的最优结果 子问题之间必须相互独立 通过改造问题来优化由于子问题之间不独立而导致的最优子结构失效的情况: 问题: 假设学校有10个班,已知每个班的最高分与最低分差值的最大分数差,需要计算全校学生中的最大分数差 分析: 这样的问题就无法通过这10个班的最大分数差来推导出来,因为这10个班的最大分数差不一定就包含全校学生的最大分数差.比如全校的最大分数差可能是由8班的最高分和6班的最低分的分数差而得.这样就导致子问题之间不是互相独立的 改造问题: 直接进行问题改造 int result = 0; for (Student a : school) { for (Student b : school) { if (a is b) { continue; } result = max(result, |a.score - b.score|) } } return result; 改造问题就是将问题等价转化: 最大分数差就等价于最高分数与最低分数的差 那么就是要求最高和最低分数 求最高分数是具备最优子结构的,求最低分数也是具有最优子结构的 这样就样一个不具备最优子结构的问题转化为具备最优子结构的子问题 借助最优子结构解决最值问题,再解决最大分数差问题 题目: 求一棵二叉树的最大值,假设节点中的值都为非负数 int maxVal(TreeNode root) { if (root == null) { return -1; } int left = maxVal(root.left); int right = maxVal(root.right); return max(root.val, left, right); }