剑指Offer:面试题31 连续子数组的最大和

来源:互联网 发布:java md5工具类运用 编辑:程序博客网 时间:2024/05/16 11:54
/*连续子数组的最大和:输入一个整形数组,数组里有整数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。分析:刚开始令sum = 0,f[i] = {iArr[i],i = 0 或者f(i-1) <= 0       {f(i-1) + iArr[i],i != 0 并且 f(i-1) > 0    动态规划:用f[i]表示以第i个数结尾的最大连续和    如果以第i-1个数字结尾的子数组的数字和小于0,如果把这个负数与第i个数字相加,结果肯定比第i个    数字本身要小,因此此时就令其为当前数字。    如果以第i-1个数字结尾的最大连续和大于0,此时加上第i个数字(不管第i个数字是否为正或为负)    加起来的和必定比第i个数字要大 输入:输入有多组数据,每组测试数据包括两行。第一行为一个整数n(0<=n<=100000),当n=0时,输入结束。接下去的一行包含n个整数(我们保证所有整数属于[-1000,1000])。输出:对应每个测试案例,需要输出3个整数单独一行,分别表示连续子向量的最大和、该子向量的第一个元素的下标和最后一个元素的下标。若是存在多个子向量,则输出起始元素下标最小的那个。样例输入:3-1 -3 -25-8 3 2 0 586 -3 -2 7 -15 1 2 20样例输出:-1 0 010 1 48 0 3*//*关键:1 f[i] = {iArr[i],i = 0 或者f(i-1) <= 0       {f(i-1) + iArr[i],i != 0 并且 f(i-1) > 0    动态规划:用f[i]表示以第i个数结尾的最大连续和2 要保存当前的累加和与之前的最大累加和进行比较  if(lSum > lMaxSum)*/#include <stdio.h>#include <string.h>const int MAXSIZE = 100001;int iArr[MAXSIZE];void maxSubArrSum(int n){ long long lSum = 0,lMaxSum = iArr[0]; int iNewBegIndex = 0,iNewEndIndex = 0; int iBegIndex = 0,iEndIndex = 0; for(int i = 0 ; i < n ; i++) {  if(lSum <= 0)  {   lSum = iArr[i];//这里需要重新记录最大连续子数组的起始下标   iNewBegIndex = i;  }  else  {   lSum += iArr[i];   iNewEndIndex = i;  }  if(lSum > lMaxSum)  {   lMaxSum = lSum;   iBegIndex = iNewBegIndex;//更新最大连续子数组的起始下标   iEndIndex = iNewEndIndex;  } } printf("%lld %d %d\n",lMaxSum,iBegIndex,iEndIndex);//注意是:%lld,而不是%d}void process(){ int n; while(EOF != scanf("%d",&n)) {  if(n == 0)  {   break;  }  if( n < 0 || n >= MAXSIZE)  {   continue;  }  memset(iArr,0,sizeof(iArr));  for(int i = 0 ; i < n ;i++)  {   scanf("%d",&iArr[i]);  }  maxSubArrSum(n); }}int main(int argc,char* argv[]){ process(); getchar(); return 0;}


 

0 0
原创粉丝点击