题目描述
输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为 O(n).
[1,-2,3,10,-4,7,2,-5]
18
输入的数组为{1,-2,3,10,—4,7,2,一5},和最大的子数组为{3,10,一4,7,2},因此输出为该子数组的和 18。
首先我们来最简单的暴力解法: 时间复杂度是O(N^2),空间复杂度是O(1)
public class Solution {
int max = Integer.MIN_VALUE;
public int FindGreatestSumOfSubArray(int[] array) {
//可以用O(N)的时间复杂度解决
//但如果是用O(N^2)的时间复杂度也是可以的
//比如暴力解法,用双指针
for(int i = 0 ; i < array.length; i++)
{
int temp = 0;
for(int j = i; j < array.length; j++)
{
temp += array[j];
max = Math.max(max , temp);
}
}
return max;
}
}
-
接下来我们优化处理:
-
用动态规划来做
-
时间复杂度是O(N),空间复杂度也是O(N)
public class Solution {
int max = Integer.MIN_VALUE;
public int FindGreatestSumOfSubArray(int[] array) {
//那其实这个题,我们还可以用动态规划来做
//定义一个长度跟数组长度一样长的dp数组,dp[i]代表的是,以array[i]结尾时,最大的子数组和是多少
int[]dp = new int[array.length];
dp[0] = array[0];
for(int i = 1; i < array.length; i++)
{
if(dp[i - 1] <= 0)
{
dp[i] = array[i];
}
else
{
dp[i] = dp[i - 1] + array[i];
}
max = Math.max(max , dp[i]);
}
return max;
}
}
- 我们还可以更优化
- 时间复杂度O(N),空间复杂度O(1)
public class Solution {
int max = Integer.MIN_VALUE;
public int FindGreatestSumOfSubArray(int[] array) {
//如果是O(N)的时间复杂度,不借助其他空间
//永远存放之前连续的最大和
int preSum = 0;
//如果之前的和小于0,再加上一个小于0的,就更小,所以preSum = current;
//
for(int i = 0; i < array.length; i++)
{
if(preSum < 0)
{
preSum = array[i];
}
else
{
preSum += array[i];
}
max = Math.max(max , preSum);
}
return max;
}
}