目录
1. 题意
2. 思路
2.1. 状态表示
2.2. 状态转移方程
2.3. 初始化
2.4. 填表顺序
2.5. 返回值
3. 编码
1. 题意
链接: 53. 最大子数组和 - 力扣(LeetCode)
题目
给你一个整数数组 nums
,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组是数组中的一个连续部分。
示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例 2:
输入:nums = [1]
输出:1
示例 3:
输入:nums = [5,4,-1,7,8]
输出:23
提示:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
进阶:如果你已经实现复杂度为 O(n)
的解法,尝试使用更为精妙的 分治法 求解。
子数组:
2. 思路
2.1. 状态表示
dp[i]: 以 i 位置为结尾, 所有子数组中的最大和.
2.2. 状态转移方程
要分析状态转移方程, 我们先聚焦于一个 dp[i] 位置来进行分析:
整体可以分为两类:
- 长度 == 1
- 长度 > 1
所以, 我们的 dp[i] = max(nums[i], nums[i] + dp[i-1])
.
2.3. 初始化
因为我们的 dp[i] 依赖 dp[i-1], 因此我们需要初始化 dp[0], 下面提供两种思路:
方式 1: 初始化 dp[0] = nums[0]
方式 2: 添加虚拟节点, dp[0] = 0;// 虚拟节点
-> 不过需要注意下标的映射关系.
2.4. 填表顺序
从左到右(这是状态转移方程所决定的).
2.5. 返回值
返回以 i 位置为结尾的子数组的最大值
for(int i = 0; i < n; i++)
{ret = max(dp[i], ret);
}return ret;
3. 编码
class Solution {
public:int maxSubArray(vector<int>& nums) {// dp[i]表示: 以i位置为结尾, 最大的一个子数组之和// 1. 创建dp表int n = nums.size();vector<int> dp(n+1, 0);// 2. 初始化// 3. 赋值int m = INT_MIN;for(int i = 1; i <= n; i++){dp[i] = max(nums[i-1], dp[i-1] + nums[i-1]);if(dp[i] > m) m = dp[i];}// 4. 返回return m;}
};
注意点:
- 略.