题目:给一个数组,让求连续数组元素的最大和。
public int maxsumofSubarray (int[] arr)
思路:
连续子数组的最大和 动态规划 dp[i]
dp[i]表示以arr[i]结尾的连续子数组的最大和。arr[i]必须加上,就不判断arr[i]是正还是负。
dp[i]等于arr[i]加上以上一个元素为结尾的最大和dp[i-1],但是需要判断dp[i-1]的正负,如果是正的则加上,负的就不加,加0。
时间复杂度为O(n),空间复杂度为O(1),所以只能在arr上修改,不能创建新数组dp。
动态规划都不创建dp[],省O(n)空间。都不修改原arr[],只用中间变量来保存中间结果。
新(不修改arr数组,只用中间变量保存中间结果):
/*
动态规划,不用创建dp[]省空间,而且不用修改原数组arr。
只用几个中间变量保存中间的值。
*/
public int maxsumofSubarray2 (int[] arr) {
int maxSum = arr[0],temp = 0,preTemp = arr[0];
for (int i = 1; i < arr.length; i++) {
temp = arr[i] + (preTemp > 0 ? preTemp : 0);
if(temp > maxSum) maxSum = temp;
preTemp = temp;
}
return maxSum;
}
旧(修改arr数组):
/*
求子数组的最大和 动态规划 dp[i]
dp[i]表示以arr[i]元素结尾的子数组的最大和。
arr[i]必须加上,所以不判断arr[i]的正负
dp[i]等于arr[i]加上dp[i-1],也就是之前元素和的最大值
所以判断dp[i-1]的正负,正的话就加上,负的话就不加,加0
时间复杂度为O(n),空间复杂度为O(1),所以只能在arr上修改
*/
public int maxsumofSubarray (int[] arr) {
int maxSum = arr[0];
for (int i = 1; i < arr.length; i++) {
arr[i] += (arr[i - 1] >= 0 ? arr[i - 1] : 0);
// arr[i] += Math.max(arr[i - 1],0);
if(arr[i] > maxSum) maxSum = arr[i];
}
return maxSum;
}