53. 最大子序和

 

 

 

很经典的DP题,用dp[i]纪录[0,i]的数组的最大子序和,往后递推实际上就是判断

nums[i+1]是否能给dp[i+1]带来增益效果,使得dp[i+1]>dp[i]

public int maxSubArray(int[] nums) {
        // dp[i]纪录以截至i结尾的最大子序和
        int[] dp = new int[nums.length];
        // 初始化累加和
        dp[0] = nums[0];
        int max = nums[0];
        for (int i = 1; i < nums.length; i++) {
            // 存在可能情况为(1)nums[i]对dp[i-1]为增益效果(nums[i]>0)
            // (2)dp[i-1]对nums[i]为减益效果(dp[i-1]<0)
            dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
            max = Math.max(max, dp[i]);
        }
        return max;
    }

我们发现其实每次的dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);

实际上就是比较增益效果,实际上当dp[i-1]<0的时候,我们就可以

确定dp[i-1]必然为减益效果,根本不需要去做比较,直接就是dp[i]=nums[i],

因此我们可与将dp数组简化为sum变量,每次小于0时就直接令其等于nums[i]

public int maxSubArray(int[] nums) {
        int max=nums[0],sum=0;
          for(int i=0;i<nums.length;i++){
              if(sum>0){
                  sum+=nums[i];
              }else{
                  sum=nums[i];
              }
              max=Math.max(max,sum);
          }
          return max;
    }

 

时间复杂度O(n),空间复杂度O(1)

posted @ 2021-03-26 10:40  jchen104  阅读(42)  评论(0编辑  收藏  举报