问题:输入一个整形数组,里面又正数也有负数。数组中一个或连续多个整数组成一个子数组,求所有子数组和的最大值。
典型的动态规划思想,因为每个状态都和前一个状态紧密相关。
因为这是一个一维数组,所以我们优先考虑用一维数组dp来做。
1、维护一个dp数组,dp[i]表示以第i个位置结尾的子数组的和的最大值。
2、边界条件,dp[0] = nums[0];
3、状态转移方程,这里我们要分两种情况:第一种如果nums[i]<=0,那么dp[i]=dp[i-1];否则dp[i] = dp[i-1]+nums[i]。其实也就是dp[i] = max{dp[i-1],dp[i-1]+nums[i]}。
1 public int maxsum(int[] nums){ 2 int[] dp = new int[nums.length]; 3 dp[0] = nums[0]; 4 for ( int i = 1 ; i < nums.length ; i ++ ){ 5 if ( dp[i-1] <= 0 ) dp[i] = nums[i]; 6 else dp[i] = dp[i-1] + nums[i]; 7 } 8 int max = Integer.MIN_VALUE; 9 for ( int num : dp ) { 10 max = Math.max(max,num); 11 } 12 return max; 13 }
在这里可以考虑如果连续数组必须>=2的个数,如果全部都是负数怎么办。
可以把这个情况作为单独讨论,如果数组全负,且都得>=2,拿出来单独做一次循环,相邻两个数字相加取最小就可以了。