LeetCode HOT 100题目解析——动态规划:最大子序和(Java详细讲解)
一、题目介绍
本次解析的是力扣HOT 100中的经典题目:53. 最大子序和
题目描述:
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
二、解题思路讲解
本题考察的是动态规划(Dynamic Programming),主要思路是:
- 定义状态:
- 用
dp[i]
表示以i
结尾的最大连续子数组和。
- 用
- 状态转移方程:
dp[i] = max(nums[i], dp[i-1] + nums[i])
- 意思是:要么当前数字自己成为新的子数组,要么和前面的子数组连起来。
- 初始值:
dp[0] = nums[0]
- 答案:
- 遍历整个数组,找出最大的
dp[i]
即可。
- 遍历整个数组,找出最大的
优化:实际上我们只需要前一个状态,可以不用数组,直接用一个变量记录即可。
三、Java代码实现(含详细注释)
public class Solution {
public int maxSubArray(int[] nums) {
int maxSum = nums[0]; // 最大子序和,初始为第一个元素
int currentSum = nums[0]; // 以当前位置结尾的最大和
for (int i = 1; i < nums.length; i++) {
// 如果前面的和加当前值还不如当前值本身大,就抛弃前面的,重新开始
currentSum = Math.max(nums[i], currentSum + nums[i]);
// 更新最大子序和
maxSum = Math.max(maxSum, currentSum);
}
return maxSum;
}
}
代码说明:
currentSum
表示以当前位置结尾的最大连续和。- 如果
currentSum + nums[i]
还不如nums[i]
,那么直接重新开始。 - 每次都更新
maxSum
,保存目前全局最大值。 - 时间复杂度O(n),空间复杂度O(1)。
四、小结
本题是动态规划的入门题目,适合所有算法初学者掌握。学会本题后可以解决许多类似的区间和最大值问题。
希望本讲解能帮助你理解“动态规划”技术,欢迎继续关注LeetCode HOT 100题目解析!