难度:easy
1、题目介绍
2、思路解析
一、第一种方法:暴力法,时间复杂度:
使用俩个指针,i 和 j ,不断移动 j指针,得到以 5 为首的所有子序列
[5,4] [5,4,-1] [5,4,-1,7] [5,4,-1,7,8]。
并求出每个子序列的和sum:sum = sum + num [ j ]
[5,4] = 9 [5,4,-1] =8 [5,4,-1,7] =15 [5,4,-1,7,8]=23
对maxSum与sum求得最大值: maxSum = Math.max(sum,maxSum) = 23.
i 后移一位,找出以 4 为首的所有子序列并求出和。[4,-1] = 3 [4,-1,7] =10 [4,-1,7,8] = 18 。maxSum的最大值还是23
直到遍历到数组的末尾为止。
代码:
int sum ;
int maxSum = nums[0];
for (int i = 0; i < nums.length; i++) {
sum = 0 ;
for (int j = i; j < nums.length; j++) {
sum = sum + nums[j];
maxSum = Math.max(sum,maxSum);
}
}
return maxSum ;
注意:★★★★★
j = i : j 总是从 i 的位置开始遍历
int maxSum = nums[0]: 如果数组中只有一个元素,并且是负数,直接返回
sum = 0:j 指针每遍历完一次都要将sum置0,不然还会保存上次 循环的值
二、第二种方法:动态规划法,时间复杂度:
思路解析:
每遍历一个元素,都会找到以当前元素为末尾元素的最大子序列和。那么就会有俩个策略:
dp[ i ] : 数组保存的是每个元素的最大子序列的和
(1)最大子序列和就是当前元素的值 nums[ i ]
(2)当前元素的值加上前一个元素最大子序列和的值 nums[ i ]+dp[ i-1 ]
1、首先用maxSum保存最大子序列的和。当遍历第一个元素 5 时,maxSum = 5.。
2、当遍历到第二个元素 4 时,第一种策略:4,第二种策略:9。然后比较俩种策略的最大值:dp[i] = Math.math(nums[ i ], nums[ i ]+dp[ i-1 ]) = 9;对dp[i]和maxSum取得最大值,maxSum = Math.math(dp[ i ], maxSum) = 9;
3、当遍历第三个元素-1时,第一种策略:-1 第二种 策略:8, dp[i] = 8 ,maxSum = 9
4、当遍历到第四各元素7时,第一种策略:7 第二种策略:15,dp[i] =15.maxSum = 15
5、当遍历到第五个元素 8时,第一种策略:8,第二种策略:23,dp[i] = 23,maxSum = 23.
代码:
//动态规划
int maxSum = nums[0];
int dp[] = new int[nums.length];
dp[0] = nums[0];
for (int i = 1; i < nums.length; i++) {
dp[i] = Math.max(nums[i], dp[i - 1] + nums[i]);
maxSum = Math.max(dp[i], maxSum);
}
return maxSum;