我是靠谱客的博主 繁荣星月,这篇文章主要介绍【JZ42 连续子数组的最大和】,现在分享给大家,希望可以做个参考。

描述

输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,子数组最小长度为1。求所有子数组的和的最大值。
数据范围:
1 <= n <= 2×105

−100 <= a[i] <= 100

要求:时间复杂度为 O(n),空间复杂度为 O(n)
进阶:时间复杂度为 O(n),空间复杂度为 O(1)

示例1

复制代码
1
2
3
4
5
6
输入:[1,-2,3,10,-4,7,2,-5] 返回值:18 说明:经分析可知,输入数组的子数组[3,10,-4,7,2]可以求得最大和为18

示例2

复制代码
1
2
3
4
输入:[2] 返回值:2

示例3

复制代码
1
2
3
4
输入:[-10] 返回值:-10

方法一:动态规划 状态定义

dp[i]表示以i结尾的连续子数组的最大和。所以最终要求dp[n-1] 状态转移方程:dp[i] = max(array[i], dp[i-1]+array[i]) 解释:如果当前元素为整数,并且dp[i-1]为负数,那么当然结果就是只选当前元素 技巧:这里为了统一代码的书写,定义dp[i]表示前i个元素的连续子数组的最大和,结尾元素为array[i-1]

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution { public: int FindGreatestSumOfSubArray(vector<int> array) { //记录到下标i为止的最大连续子数组和 fast-template vector<int> dp(array.size(), 0); dp[0] = array[0]; int maxsum = dp[0]; for (int i = 1; i < array.size(); i++) { //状态转移:连续子数组和最大值 dp[i] = max(dp[i - 1] + array[i], array[i]); //维护最大值 maxsum = max(maxsum, dp[i]); } return maxsum; } };

运行时间:34ms
超过3.04% 用C++提交的代码
占用内存:5740KB
超过14.05%用C++提交的代码
时间复杂度:O(n) 空间复杂度:O(n)

方法二:空间复杂度O(1)解法

思想很简单,就是对下标为i的元素array[i],先试探的加上array[i], 如果和为负数,显然,以i结尾的元素对整个结果不作贡献。 具体过程:

  1. 初始化:维护一个变量tmp = 0
  2. 如果tmp+array[i] < 0, 说明以i结尾的不作贡献,重新赋值tmp = 0
  3. 否则更新tmp = tmp + array[i] 最后判断tmp是否等于0, 如果等于0, 说明数组都是负数,选取一个最大值为答案。

代码 :

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution { public: int FindGreatestSumOfSubArray(vector<int> array) { int ret = 0; int tmp = 0; for (const int k : array) { if (tmp + k < 0) { tmp = 0; } else { tmp += k; } ret = max(ret, tmp); } if (ret != 0) return ret; return *max_element(array.begin(), array.end()); } };

运行时间:32ms
超过4.34% 用C++提交的代码
占用内存:5692KB
超过15.83%用C++提交的代码
时间复杂度:O(n) 空间复杂度:O(1)

最后

以上就是繁荣星月最近收集整理的关于【JZ42 连续子数组的最大和】的全部内容,更多相关【JZ42内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(110)

评论列表共有 0 条评论

立即
投稿
返回
顶部