题目描述
输入一个长度为n
的整型数组array
,数组中的一个或连续多个整数组成一个子数组,找到一个具有最大和的连续子数组。
- 1.子数组是连续的,比如
[1,3,5,7,9]
的子数组有[1,3]
,[3,5,7]
等等,但是[1,3,7]
不是子数组 - 2.如果存在多个最大和的连续子数组,那么返回其中长度最长的,该题数据保证这个最长的只存在一个
- 3.该题定义的子数组的最小长度为
1
,不存在为空的子数组,即不存在[]是某个数组的子数组 - 4.返回的数组不计入空间复杂度计算
示例 1
输入:[1,-2,3,10,-4,7,2,-5]
返回值:[3,10,-4,7,2]
说明:经分析可知,输入数组的子数组[3,10,-4,7,2]可以求得最大和为18,故返回[3,10,-4,7,2]
示例 2
输入:[1]
返回值:[1]
思路 & 解答
这道题是比较经典的动态规划,假设现在有 n 个元素,突然加上一个元素,变成 n+1 个元素,对连续子数组的最大和有什么影响呢?
我们只需要知道以每一个元素结尾的最大连续子数组,再维护一个最大的值即可。
假设数组为num[]
,用 dp[i]
表示以下标 i
为终点的最大连续子数组和,遍历每一个新的元素nums[i+1]
,以 num[i+1]
为连续子数组的情况只有两种:
- dp[i] + num[i+1]
- 只有num[i+1]
所以以nums[n]
结尾的最大连续子数组和为:
$$ dp[i] = max(dp[i-1] + nums[i],nums[i]) $$
在计算的过程中,需要维护一个最大的值,并且把该连续子数组的左边界以及右边界维护好,最后根据维护的区间返回。
Java
代码实现如下:
public class Solution85 {
public int[] FindGreatestSumOfSubArray(int[] array) {
int[] dp = new int[array.length];
dp[0] = array[0];
int maxsum = dp[0];
int left = 0, right = 0;
int maxLeft = 0, maxRight = 0;
for (int i = 1; i < array.length; i++) {
right++;
dp[i] = Math.max(dp[i - 1] + array[i], array[i]);
if (dp[i - 1] + array[i] < array[i]) {
left = right;
}
// 更新最大值以及更新最大和的子数组的边界
if (dp[i] > maxsum
|| dp[i] == maxsum && (right - left + 1) > (maxRight - maxLeft + 1)) {
maxsum = dp[i];
maxLeft = left;
maxRight = right;
}
}
// 保存结果
int[] res = new int[maxRight - maxLeft + 1];
for (int i = maxLeft, j = 0; i <= maxRight; i++, j++) {
res[j] = array[i];
}
return res;
}
}
C++
代码如下:
class Solution {
public:
vector<int> FindGreatestSumOfSubArray(vector<int> &array) {
vector<int> dp(array.size(), 0);
dp[0] = array[0];
int maxsum = dp[0];
int left = 0, right = 0;
int maxLeft = 0, maxRight = 0;
for (int i = 1; i < array.size(); i++) {
right++;
dp[i] = max(dp[i - 1] + array[i], array[i]);
if (dp[i - 1] + array[i] < array[i]) {
left = right;
}
// 更新最大值以及更新最大和的子数组的边界
if (dp[i] > maxsum
|| dp[i] == maxsum && (right - left + 1) > (maxRight - maxLeft + 1)) {
maxsum = dp[i];
maxLeft = left;
maxRight = right;
}
}
// 保存结果
vector<int> res;
for (int i = maxLeft, j = 0; i <= maxRight; i++, j++) {
res.push_back(array[i]);
}
return res;
}
};