面试题31.连续子数组的最大和
2015-09-01 15:45
537 查看
题目:输入一个整型数组,数组里有正数也有负数。数组中一个或者连续多个整数组成一个子数组。
求所有子数组的和的最大值。要求时间复杂度O(n)
本题可以把所有子数组全部找出来再求其和的最大值便可以得出,但是这样会导致算法的时间复杂度
为0(n^2),所以有两种方法来解决这个问题。
方法1.数组扫描
我们扫描一遍数组并且累加数组元素的和,当遇到累加和为负数的时候,我们从数组中
下一个元素开始重新累加。直到遍历完成。
方法2.动态规划的方法
有这样一个公式
{ pdata[i] if f(i-1)<=0
f(i){
{f(x-i)+pdata[i] if f(i-1)>0
怎么理解呢,f(i)是一个数组,其代表数组中第1-i个子数组的最大和,当f(i-1)为负的时候,此时加上一个pdata[i]会更小
所以f(i)=pdata[i]
当f(i-1)为正的时候,此时加上一个pdata[i]会更大,所以f(i)=f(i-1)+pdata[i];
下面我们分别实现两种方法:
第一种扫描法(如果只想找最大的则不必找出最大子数组到底是哪些元素,复杂度0(n))
运行结果:
2.动态规划的方法(f(i)为存储0-i子数组的最大和)
运行截图:
求所有子数组的和的最大值。要求时间复杂度O(n)
本题可以把所有子数组全部找出来再求其和的最大值便可以得出,但是这样会导致算法的时间复杂度
为0(n^2),所以有两种方法来解决这个问题。
方法1.数组扫描
我们扫描一遍数组并且累加数组元素的和,当遇到累加和为负数的时候,我们从数组中
下一个元素开始重新累加。直到遍历完成。
方法2.动态规划的方法
有这样一个公式
{ pdata[i] if f(i-1)<=0
f(i){
{f(x-i)+pdata[i] if f(i-1)>0
怎么理解呢,f(i)是一个数组,其代表数组中第1-i个子数组的最大和,当f(i-1)为负的时候,此时加上一个pdata[i]会更小
所以f(i)=pdata[i]
当f(i-1)为正的时候,此时加上一个pdata[i]会更大,所以f(i)=f(i-1)+pdata[i];
下面我们分别实现两种方法:
第一种扫描法(如果只想找最大的则不必找出最大子数组到底是哪些元素,复杂度0(n))
#include <iostream> using namespace std; int FindSerialMaxSum(int* pData,int nLength) { int CurrSum=0; int MaxSum=0; if(pData==NULL||nLength==0) return 0; int *ChildArray=new int[nLength]; for(int k=0;k<nLength;k++) ChildArray[k]=0; int index=0; for(int i=0;i<nLength;i++) { if(CurrSum<=0) { CurrSum=pData[i]; for(int j=0;j<nLength;j++) ChildArray[j]=0; index=0; ChildArray[index]=pData[i]; } else { CurrSum+=pData[i]; index++; ChildArray[index]=pData[i]; } if(CurrSum>MaxSum) MaxSum=CurrSum; } int Temp=0; cout<<"The Child Array is : "; for(int l=0;pData[l]!=0;l++) { if(Temp==MaxSum) { break; } Temp+=ChildArray[l]; cout<<ChildArray[l]<<" "; } cout<<endl; return MaxSum; } int main(int argc ,char* argv[]) { int pdata[]={1,-2,3,10,-4,7,2,-5}; int nLength=8; int SerivalSum=FindSerialMaxSum(pdata,nLength); if(SerivalSum!=0) cout<<"The Serial Max Sum = "<<SerivalSum<<endl; else cout<<"Input error!"<<endl; system("pause"); return 0; }
运行结果:
2.动态规划的方法(f(i)为存储0-i子数组的最大和)
#include <iostream> using namespace std; int FindSerialMaxSum(int* pData,int nLength,int* f) { f[0]=pData[0]; int MaxSum=0; for(int i=1;i<nLength;i++) { if(f[i-1]<=0) { f[i]=pData[i]; } else { f[i]=f[i-1]+pData[i]; } if(f[i]>MaxSum) MaxSum=f[i]; } for(int k=0;k<nLength;k++) { cout<<f[k]<<" "; } cout<<endl; return MaxSum; } int main(int argc ,char* argv[]) { int pdata[]={1,-2,3,10,-4,7,2,-5}; int nLength=8; int *f=new int[nLength]; int SerivalSum=FindSerialMaxSum(pdata,nLength,f); if(SerivalSum!=0) cout<<"The Serial Max Sum = "<<SerivalSum<<endl; else cout<<"Input error!"<<endl; delete[] f; system("pause"); return 0; }
运行截图:
相关文章推荐
- Freelancer 之潮:自由职业市场的崛起
- 程序员进阶
- 一道面试题
- 4大国外自由职业者项目外包网站
- 网友网易面试经历学习---阿冬专栏
- 程序员必备:技术面试准备手册
- 程序员之所以犯错误,不是因为他们不懂,而是因为他们自以为什么都懂。
- 黑马程序员--Java常见对象
- 每个程序员都要遵守的一些优秀编程风格
- 浅谈机器学习的职业发展方向
- 黑马程序员之集合框架2
- 黑马程序员之集合框架1
- 剑指offer-第七章面试案例1(字符串转换为整型)
- 剑指offer-第七章面试案例1(字符串转换为整型)
- 从程序员的角度来看为什么我们需要工作流 .
- 写给想当程序员的朋友
- 100个iOS开发/设计面试题汇总,你将如何作答?
- 网易校园招聘java面试经历
- 我的美国CS面试经验分享
- 面试知识储备_操作系统:处理机调度与死锁