【剑指offer】44. 连续子数组的最大和(二)
总目录:
1.问题描述
输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,找到一个具有最大和的连续子数组。
1.子数组是连续的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1,3,7]不是子数组
2.如果存在多个最大和的连续子数组,那么返回其中长度最长的,该题数据保证这个最长的只存在一个
3.该题定义的子数组的最小长度为1,不存在为空的子数组,即不存在[]是某个数组的子数组
4.返回的数组不计入空间复杂度计算
数据范围:
1<=n<=10^5
−100<=a[i]<=100
要求:时间复杂度O(n),空间复杂度O(n)
进阶:时间复杂度O(n),空间复杂度O(1)
2.问题分析
1动态规划。
每次遇到一个新的数组元素,连续的子数组要么加上变得更大,要么它本身就更大,
因此状态转移为dp[i]=max(dp[i−1]+array[i],array[i]),这是最基本的求连续子数组的最大和
注意滑动窗口的左右指针和已找到的和最大的连续序列的左右指针的维护。
3.代码实例
动态规划
1 #include <algorithm> 2 class Solution { 3 public: 4 vector<int> FindGreatestSumOfSubArray(vector<int>& array) { 5 vector<int> res; 6 7 //记录到下标i为止的最大连续子数组和 8 int dp = array[0]; 9 int maxsum = array[0]; 10 11 //滑动区间 12 int left = 0, right = 0; 13 //记录最长的区间 14 int resl = 0, resr = 0; 15 16 for (int i = 1; i < array.size(); i++) { 17 right++; 18 19 //区间新起点 20 if (dp + array[i] < array[i]) { 21 left = right; 22 } 23 24 //状态转移:连续子数组和最大值 25 dp = max(dp + array[i], array[i]); 26 27 //更新最大值 28 if (dp > maxsum || dp == maxsum && 29 (right - left + 1) > (resr - resl + 1)) { 30 maxsum = dp; 31 resl = left; 32 resr = right; 33 } 34 } 35 36 //取数组 37 for (int i = resl; i <= resr; i++) 38 res.push_back(array[i]); 39 40 return res; 41 } 42 };