一、题目描述
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。


二、解题思路
解题思路一
可以使用暴力破解法,代码中有详细注释,这里也分析一下:
首先依次遍历相加,假设当前求和是A,加上下一个数是A+i
每次加下一个数求的和A+i都要和 i 做一个比较,选出一个最大的来,这是分两种情况来考虑:
当加下一个数求的和(A+i)大于于下一个数 (i) 时,说明最大子序列可能出现在继续加后面的元素中,注意一个点,这里判断的是大于下一个数 (i),而不是大于当前和值A,来分析一下,如果我们判断条件是A+i > A,那么,当这个条件不成立时,说明 i 可能是一个负数使得 A+i 变小了,此时我们要更新初始值从 i 开始重新循环,这是不对的,可能在A这个和中保留了最大值,只是刚好遇到了 i 使得和变小,如果加上 i+1 ,假如此时和值 A+i + (i+1) 能保证有最大子序和呢?不知道你能明白这一点不。
如果我的判断条件是A+i >= i,就是当当前和加下一个数大于下一个数时,这个不成立的条件是 i 前面的数加上我本身的和都比我小,那前面的数就没必要作为最大子序列中的值了,直接以我为起点计算就行,这样的判断条件就避免的上面的情况,就是当A+i 变小了,不会重新从 i 开始,仍然会保留A+i求和的部分,所以这里的判断条件A+i >= i才是对的。
解题思路二
这道题的普遍思路是动态规划求解,动态规划的是首先对数组进行遍历,当前最大连续子序列和为 sum,结果为 ans。
如果 sum > 0,则说明 sum 对结果有增益效果,则 sum 保留并加上当前遍历数字
如果 sum <= 0,则说明 sum 对结果无增益效果,需要舍弃,则 sum 直接更新为当前遍历数字
每次比较 sum 和 ans的大小,将最大值置为ans,遍历结束返回结果
时间复杂度:O(n)
三、代码演示
代码演示一
class Solution {
public int maxSubArray(int[] nums) {
/*
暴力破解,利用两个变量,一个记录最大和,一个记录当前遍历的元素求和
*/
//记录元素的求和
int current_num = nums[0];
//记录所有和中的最大值
int max_num = current_num;
for(int i=1; i<nums.length; i++){
/*
判断当前序列加上下一个元素的值大于下一个元素,表明最大子序列可能出现在后续序列中,记录此时的最大值
*/
if(current_num+nums[i]>nums[i]){
//更新最大子序列元素和
current_num += nums[i];
//更新最大和值
max_num = Math.max(max_num, current_num);
}else{
/*
这种情况是当当前的最大子序列和小于下一个元素时,那么就要将下一个元素作为当前
子序列的起始点值
*/
int m = Math.max(max_num, current_num+nums[i]);
max_num = Math.max(m, nums[i]);
//更新起始点
current_num = nums[i];
}
}
return max_num;
}
}
代码演示二
class Solution {
public int maxSubArray(int[] nums) {
int ans = nums[0];
int sum = 0;
for(int num: nums) {
if(sum > 0) {
sum += num;
} else {
sum = num;
}
ans = Math.max(ans, sum);
}
return ans;
}
}
388

被折叠的 条评论
为什么被折叠?



