最大字串和问题 个人剖析
来源:互联网 发布:手机c语言程序编写软件 编辑:程序博客网 时间:2024/04/30 15:50
input: int a[1..n], with positive and negative integers
output: the max sum of continuous integers, if all negative, return 0;
O(n^3):(具体计算见最下面)
max=0;
for starti=1->n
for leni=1->n-starti+1
sum=0;
for j=starti->starti+leni-1
sum+=a[j];
end
if(max<sum)//可以不用加完了在判断是否比当前最大值大,没加一次都判断,减少了清0操作
max=sum;
end
end
O(n^2):
max=0
for starti=1->n
sum=0;
for leni=1->n-starti+1
sum+=a[starti+leni-1];
if(max<sum)
max=sum;
end
end
O(n):DP
虽然之前上课学过,但是也知道用DP效率最高,但是今天再次写递推方程的时候还是会卡壳。
b[j]:a[1..j]中包含a[j]的最大字段和
b[j]=max{b[j-1]+a[j],a[j]}; 2<=j<=n
=a[j] j=1
(这里最容易忘记的一点是b[j]是表示包含a[j]的子问题最优解,而不是原始问题的子问题最优解。做完之后,再遍历一遍b[j]就可以求解最大值了)
1.递推的时候,判断b[j-1],>0 加上a[j],<0 赋上a[j],而且每次只许保存当前b[j],之前的1..j-1都不需要,因为已经把之前b[1..j-1]的最大用一个max记录下来了。
2.最后的遍历b[j]求最大,又可以优化,因为b[j]问题的最后解是从1->n递推过去的时候逐步保存的,并且始终记录当前最大即可
int b=0,max=0;
for j=1->n
if b>0
b+=a[j];
else
b=a[j];
end
if max<b
max=b;
end
end
这个算法经典在于:
本来DP需要保存b[1..n] 然后最后再遍历一遍求最大。但是可以用一个b保存,而且还省去最后遍历求最大的过程,这两步优化是同时进行的。
Proof:
O(n)^3
每次子序列求和,起始位置在1的有子序列长度有1,2,3.。。n,1+2+...+n
起始位置在2 2,3.。。n,2+...+n
起始位置在3 3.。。n,3+...+n
。。。
起始位置在n 1
通项an=1+..+n=n(n+1)/2
求Sn
Sn={1*2/2+2*3/3+...+n(n+1)}/2
={1*(1+1)+2*(2+1)+...+n(n+1)}/2//most important 技巧!!!!
={1^2+...n^2+1+2...+n}/2
={1/6*n(n+1)*(2*n+1)+n(n+1)/2}/2
=O(n^3)
output: the max sum of continuous integers, if all negative, return 0;
O(n^3):(具体计算见最下面)
max=0;
for starti=1->n
for leni=1->n-starti+1
sum=0;
for j=starti->starti+leni-1
sum+=a[j];
end
if(max<sum)//可以不用加完了在判断是否比当前最大值大,没加一次都判断,减少了清0操作
max=sum;
end
end
O(n^2):
max=0
for starti=1->n
sum=0;
for leni=1->n-starti+1
sum+=a[starti+leni-1];
if(max<sum)
max=sum;
end
end
O(n):DP
虽然之前上课学过,但是也知道用DP效率最高,但是今天再次写递推方程的时候还是会卡壳。
b[j]:a[1..j]中包含a[j]的最大字段和
b[j]=max{b[j-1]+a[j],a[j]}; 2<=j<=n
=a[j] j=1
(这里最容易忘记的一点是b[j]是表示包含a[j]的子问题最优解,而不是原始问题的子问题最优解。做完之后,再遍历一遍b[j]就可以求解最大值了)
1.递推的时候,判断b[j-1],>0 加上a[j],<0 赋上a[j],而且每次只许保存当前b[j],之前的1..j-1都不需要,因为已经把之前b[1..j-1]的最大用一个max记录下来了。
2.最后的遍历b[j]求最大,又可以优化,因为b[j]问题的最后解是从1->n递推过去的时候逐步保存的,并且始终记录当前最大即可
int b=0,max=0;
for j=1->n
if b>0
b+=a[j];
else
b=a[j];
end
if max<b
max=b;
end
end
这个算法经典在于:
本来DP需要保存b[1..n] 然后最后再遍历一遍求最大。但是可以用一个b保存,而且还省去最后遍历求最大的过程,这两步优化是同时进行的。
今天刷leetcode居然发现还犯了遍历b[j]来找maxsum的问题。。悲剧啊,都写过的东西。而且发现其实可以处理最大和为负数的情况,而不需要返回一个0
附属代码:
int maxSubArray(int A[], int n) { int b=A[0],sum=b; for(int i=1;i<=n-1;i++) { if(b>0) b+=A[i]; else b=A[i]; if(sum<b) sum=b; } return sum; }
Proof:
O(n)^3
每次子序列求和,起始位置在1的有子序列长度有1,2,3.。。n,1+2+...+n
起始位置在2 2,3.。。n,2+...+n
起始位置在3 3.。。n,3+...+n
。。。
起始位置在n 1
通项an=1+..+n=n(n+1)/2
求Sn
Sn={1*2/2+2*3/3+...+n(n+1)}/2
={1*(1+1)+2*(2+1)+...+n(n+1)}/2//most important 技巧!!!!
={1^2+...n^2+1+2...+n}/2
={1/6*n(n+1)*(2*n+1)+n(n+1)/2}/2
=O(n^3)
0 0
- 最大字串和问题 个人剖析
- 最大字串和问题
- 最大字串匹配问题
- 最大公共字串问题
- 最大字串和_2
- 最大字串和
- 最大字串和
- 最大连续字串和
- 最大连续字串和
- NYOJ 44 字串和 372 巧克力 (最大连续字串和问题)
- 数据机构-----求最大字串数据和问题
- 分治连续和最大字串
- 最大连续字串和、积
- 3求最大字串和
- 最大数字序列和问题,买卖股票问题,以及最长公共字串问题
- 编程珠玑 求解最大字串和
- nyoj44最大字串和(动态规划)
- poj-2479 Maximum sum 【最大字串和】
- 使用Lua实现链表的各种操作
- c# 修饰符概况
- 常用Javascript数据验证(二)
- gsoap没有输出参数问题
- sizeof和sizeof(string) (很好的文章,逻辑清楚,解释了很多模糊的概念)
- 最大字串和问题 个人剖析
- sleep与wait的区别
- Linux 开启VNCSERVER
- [动态规划]UVA103 - Stacking Boxes
- hough变换检测直线和圆
- Annotation(二):反射与Annotation、系统内建的 注释Annotation的注释
- 隆重果壳2代智能手表 Android Wear并非仅有
- linux/android系统FIMC(FullyInteractive Mobile Camer)模块及驱动详细文档
- Nosql 数据管理系统与模型的比较