很经典的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)