题目
算法思路
用 a i a_i ai 代表 n u m s [ i ] nums[i] nums[i],用 f ( i ) f(i) f(i) 代表以 n u m s [ i ] nums[i] nums[i] 结尾的连续子数组的最大和,显然我们要求的就是所有 f ( i ) f(i) f(i) 中的最大值。
动态规划转移方程:
- 若 f ( i − 1 ) ≤ 0 f(i-1) \leq0 f(i−1)≤0: f ( i ) = a i f(i)=a_i f(i)=ai
- 若 f ( i − 1 ) > 0 f(i-1)>0 f(i−1)>0: f ( i ) = f ( i − 1 ) + a i f(i)=f(i-1)+a_i f(i)=f(i−1)+ai
即, f ( i ) = m a x { f ( i − 1 ) + a i , a i } f(i)=max \{ f(i-1)+a_i,\ a_i \} f(i)=max{f(i−1)+ai, ai}
我们需要用一个数组来保存 f ( i ) f(i) f(i) 的值,用一个循环来求出所有的 f ( i ) f(i) f(i) ,但由于 f ( i ) f(i) f(i) 只与 f ( i − 1 ) f(i-1) f(i−1) 相关,因此我们可以直接在原数组 n u m s nums nums 上修改,从而让空间复杂度从 O ( n ) O(n) O(n) 降低到 O ( 1 ) O(1) O(1),类似于滚动数组的思想。
具体代码
class Solution {
public int maxSubArray(int[] nums) {
int res = nums[0];
for(int i = 1; i < nums.length; i++){
nums[i] += Math.max(nums[i - 1], 0);
res = Math.max(res, nums[i]);
}
return res;
}
}
复杂度分析
- 时间复杂度: O ( n ) O(n) O(n),n 为数组长度,因为需要遍历一遍整个数组。
- 空间复杂度: O ( 1 ) O(1) O(1)