输入一个整形数组,数组里有正数也有负数,数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和

来源:互联网 发布:怎么在淘宝外卖上开店 编辑:程序博客网 时间:2024/04/30 09:27

输入一个整形数组,数组里有正数也有负数,数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。

题目来源于:http://blog.csdn.net/v_JULY_v/archive/2010/11/12/6004660.aspx

 

思路一:

老实说我一开始看到该题目的时候到想到解法还是花了点时间,具体思路是这样,因为时间复杂度是0(n),所以我们只能用一次遍历就要求出最大的子数组和,所以我的想法是这样:以空间换取时间,用一个和原来数组一样大的临时数组记录遍历过程中的和,遍历过程中依次对每个Item都同样进行以下的动作:当遇到负数的时候,就把当前的Sum值记录到临时数组中,然后判断当前的Item的绝对值是否大于Sum,如果大于,将Sum恢复为原来的初始值,也就是Sum = 0,如果Item的绝对值小于Sum的话就把Sum += Item值。当然如果遍历过程中遇到的Item > 0的情况,直接Sum += Item.等到遍历结束后,从临时数组中捉取最大值就是最大的子数组和的值。

 

代码如下:

 

[cpp] view plaincopyprint?
  1. assert(NULL != pnArray);  
  2. if (1 == nSize) return *pnArray;  
  3.   
  4. int *pnSum = new int[nSize + 1];  
  5. assert(NULL != pnSum);  
  6.   
  7. int i32Sum = 0, i32CurValue = 0, i32Index = 0;  
  8. for (int i32I = 0; i32I < nSize; i32I++)  
  9. {  
  10.     i32CurValue = *(pnArray + i32I);  
  11.     if (i32CurValue >= 0)  
  12.     {  
  13.         i32Sum += i32CurValue;  
  14.     }  
  15.     else if ((i32CurValue < 0))  
  16.     {  
  17.         *(pnSum + i32Index++) = i32Sum;  
  18.         i32Sum = (abs(i32CurValue) > i32Sum) ? 0 : (i32Sum + i32CurValue);  
  19.     }  
  20. }  
  21. pnSum[i32Index] = i32Sum;  
  22.   
  23. if (0 != i32Index)  
  24. {  
  25.     i32Sum = *pnSum;  
  26.     for (int i32J = 1; i32J <= i32Index; i32J++)  
  27.     {  
  28.         if (*(pnSum + i32J) > i32Sum)  
  29.         {  
  30.             i32Sum = *(pnSum + i32J);  
  31.         }  
  32.     }  
  33. }  
  34.   
  35. delete [] pnSum;  
  36. return i32Sum;  
  

 

思路二:

其实这道题只要一次遍历就可以求出最大的子数组和,而且是很简单的就解决了,具体想法是这样,不断的累加每个数组元素,并用一个变量保存当前的最大值,累加的过程一直和该变量进行比对,如果大于最大值,就把当前的最大值保存下来,反复如此就可以求出最大值.

上面给出的算法太复杂,以下的算法是在上面的基础上进行改进,而且是很容易理解。代码如下:

[c-sharp] view plaincopyprint?
  1. int MaxSum(int* a, int n)  
  2. {  
  3.     int nSum = 0;  
  4.     int nValue=0;  
  5.   
  6.     for(int i = 0; i < n; i++)  
  7.     {  
  8.         if (nValue <= 0)  
  9.           nValue = a[i];  
  10.         else  
  11.           nValue += a[i];  
  12.   
  13.         if(nSum < nValue)  
  14.           nSum = nValue;  
  15.     }  
  16.   
  17.     return nSum;  
  18. }  
  19.   
  20.   
  21.   
  22.   
  23. int _tmain(int argc, _TCHAR* argv[])  
  24. {  
  25.     int anAry[] = {-2, 10,12, -20, 33};  
  26.     //int nMaxValue = MaxSubArraySum(anAry, sizeof(anAry)/sizeof(int));  
  27.   
  28.     int nMaxValue = MaxSum(anAry, sizeof(anAry)/sizeof(int));  
  29.     cout << "最大的子数组和为:" << nMaxValue << endl;  
  30.   
  31.     return 0;  
  32. }  

原创粉丝点击