思路一: 贪心法
-
用sum记录从前往后扫过的最大的连续子数组的和;
-
用curSum记录某元素前面紧挨的数组的和;
- 如果curSum小于0;说明该元素前面的子数组的和,都结果有负影响,将curSum更新为nums[i];
4)如果curSum大于0,就把curSum更新为 curSum+nums[i];
- 如果curSum小于0;说明该元素前面的子数组的和,都结果有负影响,将curSum更新为nums[i];
-
判断全局的Sum和curSum大小,更新全局的Sum;
- 时间复杂度 O(n)
class Solution {
public int maxSubArray(int[] nums) {
if (nums.length <= 0) return 0;
int curSum = nums[0];
int resSum = nums[0];
for(int i = 1; i < nums.length; i++){
if(curSum < 0){
curSum = nums[i];
}else{
curSum += nums[i];
}
if(curSum > resSum){
resSum = curSum;
}
}
return resSum;
}
}
思路二: 动态规划
- 时间: O(N);
- 空间: O(1); 优化了dp表,没有使用格外的空间开销记录历史值;
class Solution {
public int maxSubArray(int[] nums) {
if (nums.length <= 0) return 0;
int maxsum = nums[0];
// dp[i] 表示以nums[i]为结尾的连续字串最大的和;
// 初始: dp[0] = nums[0];
// 转移方程:
// 当dp[i-1] < 0. 说明dp[i-1]对dp[i]产生副作用,不如nums[i]本身对dp[i]的贡献;所以dp[i] = nums[i];
// 当dp[i-1] > 0; dp[i] = dp[i-1] + nums[i];
for(int i = 1; i < nums.length; i++){
if (nums[i-1] < 0){
nums[i] += 0;
}else{
nums[i] += nums[i-1];
}
if (maxsum < nums[i]) maxsum = nums[i];
}
return maxsum;
}
}
- 代码简洁版~~~
注意Math包是在 java.lang包下!!!!!而常见的集合实在java.util下,有必要分类记一下~~
import java.lang.Math;
public class Solution {
public int FindGreatestSumOfSubArray(int[] nums) {
if (nums.length <= 0) return 0;
int max = nums[0];
// 动态规划
// dp[i] 表示到nums[i]截止的子串最大和
// 初始: dp[0] = nums[0];
// 转移方程: dp[i] = dp[i-1] + nums[i] ifdp[i-1] > 0
// dp[i] = nums[i]; if dp[i-1] < 0;
// 优化: dp[i] 可以不用新建,直接在原数组上修改~
for(int i = 1; i < nums.length; i++){
nums[i] += Math.max(nums[i-1], 0);
max = Math.max(max, nums[i]);
}
return max;
}
}
思路三: 暴力法
- 时间: O(N^2)
- 空间: O(N)
import java.lang.Math;
public class Solution {
public int FindGreatestSumOfSubArray(int[] nums) {
// 数组为空时返回的是0还是null还是new int[0]?;
if (nums.length <= 0) return 0;
// 暴力法
int[] maxres = new int[nums.length];
int maxSum = nums[0];
for(int i = 0; i < nums.length; i++){
// maxres[i]表示以nums[i]开头的连续子串的最大和。初始值为nums[i]
maxres[i] = nums[i];
// maxres[i]不断连续累加后续的元素。
for(int j = i+1; j < nums.length; j++){
maxres[i] += nums[j];
// 如果加到某一元素其和小于0了。说明目前的累加和对后面的子串和有负影响。
if(maxres[i] < 0) maxres[i] = nums[j];
// 判断目前的累加和是不是为遍历过的所有的累加和的最大。
if(maxres[i] > maxSum) maxSum = maxres[i];
}
}
return maxSum;
}
}