题目
输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
要求时间复杂度为O(n)。
思路
要求时间复杂度为O(n),这个就不能直接用暴力法来解了,不然直接多重循环套上去,找出一个最大的数即可;但是这里要求时间复杂度为O(n),所以只能够利用动态规划来解题。
利用一个result来保存前面累加和的结果,如果前面的累加和小于0了,那么就舍弃掉,把结果赋值为0;
如果前面结果的和大于0,且本身的数值是正数也就继续累加进去即可。
代码
//动态规划题,计算子数组的最大和
class Solution {
public int maxSubArray(int[] nums) {
int length=nums.length;
int result=0;//临时结果
int max=0;//最大和
int count=0;//负数的个数
int max_sum=Integer.MIN_VALUE;//存储数组全部都是负数的情况下的最大负数值
for (int i=0;i<length;++i)
{
//处理全部数值都为负数的情况
if (nums[i]<0)
{
++count;//统计数组中负数的个数
if (nums[i]>max_sum)//找出最大的那个负数
max_sum=nums[i];
}
result+=nums[i];
if (result>max)//变大了就继续更新最大值
max=result;
else
{
//前面的和为0,舍弃掉前面的数组
if (result<0)
result=0;
}
}
if (count==length)//所有的数都是负数,只能返回一个最大的负数了
return max_sum;
return max;
}
}
结果
简单的动态规划题目,就是感觉有点繁琐。
题解思路
题解的思路就真的棒,在本身的数组上进行dp。每一个位置的最大子数组之和只有两种情况,要不就是继承前面的子数组,要不就前面子数组加上本身的数值。然后,再从这个数组中取出一个最大的来放回即可。
题解代码
class Solution {
public int maxSubArray(int[] nums) {
int length=nums.length;
int result=nums[0];
//在数组本身进行动态规划,不然就继承子结构的最优,不然就加0
for (int i=1;i<length;++i)
{
//继承子状态或者加上0
nums[i]+=Math.max(nums[i-1],0);
result=Math.max(result,nums[i]);
}
return result;
}
}
结果
题解还是强,在本身的基础上进行dp,而且还不用专门处理都是负数的情况。仰望大佬!