持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
一、题目描述:
53. 最大子数组和 - 力扣(LeetCode) (leetcode-cn.com)
给你一个整数数组 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 <= 10^5
- -10^4 <= nums[i] <= 10……4
进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。
二、思路分析:
动态规划一般适用于穷举求最值的问题,这道题很明显就是一个动态规划问题。
动态规划的一般解题步骤就是明确状态,明确选择,明确dp定义,明确base case。
这道题,状态就是“最大和”,选择是什么呢,对于数组中的每个元素 i,如果我们以 i 为最大和连续子数组的结尾数字,那么,要凑出也 i 结尾子数组的最大和,无非就两种“选择”:一是和i前面的数组相加,另一种就是自己独立为一个子数组,只有这两种情况才能保证i在子数组的最后,那么 dp[i] 和 dp[i - 1]的状态转移方程就列出来了,dp[i] = Math.max(nums[i], nums[i] + dp[i - 1]),然后我们求出穷举出来的最大值,就是我们要的结果了。
三、AC 代码:
class Solution {
public int maxSubArray(int[] nums) {
int n = nums.length;
if (0 == n) {
return 0;
}
int max = Integer.MIN_VALUE;
// dp 代表以当前数值结尾的连续子数组的最大值
int dp = 0;
for(int i = 0; i < n; i++) {
dp = Math.max(nums[i], nums[i] + dp);
max = Math.max(max, dp);
}
return max;
}
}