LeetCode0053-最大子序和
给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
https://leetcode-cn.com/problems/maximum-subarray/
核心:dp[i]的意义 :表示的是以当前位置为结尾的最大的和,必须将当前位置的数计入计算。
方法一:用两个数来记录,max用来记录,以当前位置为结尾的(当前位置必须计入计算)时,最大的和是几,不需要额外的空间
public static int maxSubArray(int[] nums) { int max = nums[0]; int premax = nums[0]; for (int i = 1; i < nums.length; i++) {
// 相当于判断max是否小于0 if (max + nums[i] > nums[i]) { max = max + nums[i]; } else { max = nums[i]; } //这一句是关键,定义一个曾经得到过的连续最大和premax,与实时的最大和做比较 if (premax < max) { premax = max; } } return premax; }
也可以这样写:
public static int maxSubArray(int[] nums) { int max = nums[0]; int premax = nums[0]; for (int i = 1; i < nums.length; i++) { // 这里相当于判断max是否小于0,如果小于0,当前位置最大值就等于nums[i],也可以如下写 // if (max + nums[i] > nums[i]) { // max = max + nums[i]; // } else { // max = nums[i]; // } if(max<0) {max=nums[i];} else {max=max+nums[i];} //这一句是关键,定义一个曾经得到过的连续最大和premax,与实时的最大和做比较 if (premax < max) { premax = max; } } return premax; }
实现二:动态规划,需要单独申请额外的数组空间用来记录每个位置上的最大值
两种方法核心思想都一样
class Solution { public int maxSubArray(int[] nums) { if(nums.length<=0) return 0; int[] dp = new int[nums.length]; dp[0] = nums[0]; int max =nums[0]; for(int i=1;i<nums.length;i++){ if(dp[i-1]<0){ dp[i]=nums[i]; }else { dp[i]=nums[i]+dp[i-1]; } max = Math.max(dp[i],max); } return max; } }