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

/*
连续子数组的最大和:
输入一个整形数组,数组里有整数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的
最大值。要求时间复杂度为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 -2
5
-8 3 2 0 5
8
6 -3 -2 7 -15 1 2 2
0
样例输出:
-1 0 0
10 1 4
8 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值