53.最大连续子数组和

题目描述:

  给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

 

1.暴力解法

  我们把所有子数组按以元素n结尾进行分类,枚举所有的情况。首先比较以某个元素n结尾的所有子数组,找到当前以n结尾的最大子数组和cur;然后将当前最大子数组和cur与已知的最大子数组和maxAns进行比较选出最大值作为新的maxAns。示例:nums=[5,4,-1,7,8]

  

 

 1 class Solution {
 2     public int maxSubArray(int[] nums) {
 3         int cur = 0;
 4         int maxAns = nums[0];
 5         for(int i =0;i<nums.length;i++){
 6             int sum = 0;
 7             for(int j =i;j>=0;j--){
 8                 sum += nums[j];
 9                 cur = Math.max(sum, nums[j]);//将累加后的值与当前已知的以n结尾的最大子数组和进行比较,决出最大值作为以n结尾的最大子数组和
10             }
11             maxAns = Math.max(maxAns,cur);//将以n结尾的最大子数组和与以其他元素结尾的最大子数组和进行比较
12         }
13         return maxAns;
14     }
15 }    

 

2.动态规划

  观察暴力法中示例数组的所有情况(如下图),可以发现每次往下计算以数组下一个元素结尾的所有子数组和时,重复计算了前面的值。

 

   另外,在我们挑选出以-1结尾的最大子数组和pre1(pre1=sum{5,4,-1}=8)后,计算以7结尾的子数组时,我们只需要基于{pre1+7,7}两种情况来决出以7结尾的最大子数组和pre2,也即延续已求得的前一个元素结尾的最大子数组和所用的子数组,添加当前元素,或者舍弃前面的子数组,由当前元素作为首元素。因为以-1结尾的其他子数组[4,--1],[-1]即使加上了元素7,必不可能大于以-1结尾的最大子数组和加上7的值,因此无需考虑那些【前一个元素结尾的非最大子数组和的子数组】。

 

  由此,可以写出动态规划转移方程:

    f(i)=max{f(i1)+nums[i],nums[i]} ,其中f(i)代表以第 i个数结尾的【连续子数组的最大和】

 

 1 class Solution {
 2     public int maxSubArray(int[] nums) {
 3         int pre = 0; //代表以当前元素结尾的最大子数组和。初始化为0,计算以首元素结尾的最大子数组和时便是两个nums[0]进行比较
 4         int maxAns = nums[0];
 5         for(int i =0;i<nums.length;i++){
 6             pre = Math.max(pre+nums[i],nums[i]);//决出以当前元素结尾的最大子数组和
 7             maxAns = Math.max(pre,maxAns);
 8         }
 9         return maxAns;
10     }
11 }

  

 

posted @ 2022-02-18 18:03  ˙鲨鱼辣椒ゝ  阅读(31)  评论(0)    收藏  举报