求一维数组中不重叠的两个子数组的最大和(百度2014年笔试题)
2014-09-20 18:00
375 查看
给定一个长度为N的整数数组a,求数组中不重叠的两个子数组的和的最大值。
如a[6]={1, 2, -4, 3, 2, -5}。所取的子数组分别为{1, 2}{3, 2}时,两个子数组的和最大,为3+5=8。
大家更熟悉的题目是求一维整数数组里的最大子数组的和。本题只是一个简单的变形。
很容易想到的解法是:
1、考虑N-1种情况,分别为将原数组拆分成长度为{1, N-1}, {2, N-2},..., {N-1, 1}的情况。
每一种情况求解前半部分与后半部分的最大子数组和,并将前半部分与后半部分的最大子数组和进行求和。
2、上述N-1种情况中所求的最大的和即题目要求的结果。
这种解法每一种情况的复杂度数O(N),N-1种情况的复杂度为O(N^2)。
进一步思考发现上述解法中不同种情况求解前半部分和后半部分的最大子数组和存在重复计算。
经过上述的分析,我们发现本题实际上是一道动态规划的题目,可以通过增加空间复杂度降低时间复杂度。
下面提出一个时间复杂度为O(N)的解法:
1、创建两个数组pre
和post
。pre[i]记录pre[0]~pre[i]中子数组的最大值,post[i]记录post[i]~post[N-1]
中子数组的最大值。
2. 下标i从0~N-2遍历pre
和post
。遍历过程中计算pre[i]+post[i+1]的值。所求的不重叠的两个子数组的最大和为
max {pre[i]+post[i+1]}, (i=0, 1, ..., N-2)。
代码如下:
如a[6]={1, 2, -4, 3, 2, -5}。所取的子数组分别为{1, 2}{3, 2}时,两个子数组的和最大,为3+5=8。
大家更熟悉的题目是求一维整数数组里的最大子数组的和。本题只是一个简单的变形。
很容易想到的解法是:
1、考虑N-1种情况,分别为将原数组拆分成长度为{1, N-1}, {2, N-2},..., {N-1, 1}的情况。
每一种情况求解前半部分与后半部分的最大子数组和,并将前半部分与后半部分的最大子数组和进行求和。
2、上述N-1种情况中所求的最大的和即题目要求的结果。
这种解法每一种情况的复杂度数O(N),N-1种情况的复杂度为O(N^2)。
进一步思考发现上述解法中不同种情况求解前半部分和后半部分的最大子数组和存在重复计算。
经过上述的分析,我们发现本题实际上是一道动态规划的题目,可以通过增加空间复杂度降低时间复杂度。
下面提出一个时间复杂度为O(N)的解法:
1、创建两个数组pre
和post
。pre[i]记录pre[0]~pre[i]中子数组的最大值,post[i]记录post[i]~post[N-1]
中子数组的最大值。
2. 下标i从0~N-2遍历pre
和post
。遍历过程中计算pre[i]+post[i+1]的值。所求的不重叠的两个子数组的最大和为
max {pre[i]+post[i+1]}, (i=0, 1, ..., N-2)。
代码如下:
#include<iostream> using namespace std; void func(int a[], const int N); int main() { const int n=10; //cin>>n; int a ={1, 2, 3, -2, 5, -4, 8, -3, -1, 3}; func(a, n); system("pause"); } void func(int a[], const int N) { int *pre=new int ; int *post=new int ; int Max=0x80000000; int temp=0; for(int i=0; i<N; i++) { if(temp<0) temp=a[i]; else { temp+=a[i]; } if(temp>Max) Max=temp; pre[i]=Max; } Max=0x80000000; temp=0; for(int i=N-1; i>=0; i--) { if(temp<0) temp=a[i]; else { temp+=a[i]; } if(temp>Max) Max=temp; post[i]=Max; } Max=0x80000000; int IDX=0; for(int i=0; i<N-1; i++) { if(pre[i]+post[i+1]>Max) { Max=pre[i]+post[i+1]; IDX=i; } } cout<<"IDX: "<<IDX<<endl; cout<<"Max: "<<Max<<endl; /*for(int i=0; i<N; i++) cout<<pre[i]<<' '; cout<<endl; for(int i=0; i<N; i++) cout<<post[i]<<' '; cout<<endl;*/ }
相关文章推荐
- 求一维数组中不重叠的两个子数组的最大和
- 百度2015校园招聘笔试题——求数组最大子序列和
- 定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,然后求出所有元素的最大值,最小值,平均值,和值,并输出出来。
- 一维静态数组_实例:寻找随机数最大值及其下标(附:源码)
- 百度面试-求多个有序数组中前n的最大值
- 求数组的连续子数组之和的最大值(一维二维)
- 求数组中n-1个元素的乘积的最大值(某公司2007年校园招聘笔试试题)
- 笔试面试之求子数组最大和
- hdu 1003 Max Sum【一维数组最大连续和】
- 2012百度实习生笔试之合并两个有序数组
- 【算法题】百度笔试题——求一组线段的最大重叠区域
- 《算法竞赛-训练指南》第一章-1.24_pre-一维数组最大连续和
- 算法--将数组分成和相等的多个子数组,求子数组的最大个数
- 求一维数组中的最大和
- 动态规划算法 (微软笔试题,求连续子数组的最大和)
- Microsoft笔试题--给定一维整数数组,找到数组里两两数之差绝对值最小的值
- 编写一个计算一维数组中所有整数的最大公约数的函数
- 算法--将数组分成和相等的多个子数组,求子数组的最大个数
- 腾讯笔试题之数组最大子序列和O(n)
- 百度笔试题合并a[0..mid]和a[mid+1,n-1],其中这两个数组分别有序