标签:数组、分治、动态规划
题目描述:
给你一个整数数组 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
思路介绍
方法1:动态规划
利用数学中的函数,用 f(i)代表以第 i 个数结尾的「连续子数组的最大和」,数组下标 [0,n-1],那么要输出的就是:
?求出每个位置的f(i),然后求f数组的最大值。
nums[i]?单独成为一段还是加入?f(i-1)f(i?1)?对应的那一段,取决于?nums[i]和?f(i-1) + nums[i]的大小
不难给出一个时间复杂度 O(n)、空间复杂度 O(n)的实现,即用一个 ff数组来保存 f(i)的值,用一个循环求出所有 f(i)。考虑到 f(i)只和 f(i-1) 相关,于是我们可以只用一个变量 pre 来维护对于当前 f(i)的 f(i-1) 的值是多少,从而让空间复杂度降低到 O(1),这有点类似「滚动数组」的思想。
class Solution {
public int maxSubArray(int[] nums) {
int pre = 0, max = nums[0];
for(int i :nums){
pre = Math.max(pre+i,i);
max = Math.max(max,pre);
}
return max;
}
}
方法2:分治
|