子数组之和的最大值

来源:互联网 发布:网络购物平台加盟 编辑:程序博客网 时间:2024/05/08 16:14

http://blog.csdn.net/songjiano/article/details/6594616

给定一个数组,查找这个数组的子数组的最大和

比如{-2,5,3,-6,4,-8,6}

输出最大和8


分析:假设已经找到一个子数组的最大和,这个子数组是从数组索引i到索引j。

可以用如下式子描述,cur_max = a[i , j]; 对于下一个数,也就是索引为j+1,这个最大和是否

将a[j+1]加入cur_max,需要考虑cur_max的值和a[j+1];

如果当前的cur_max小于0,说明a[j+1] > a[i, j] + a[j]; cur_max = a[j+1];说明此时最大值从索引j+1开始

如果当前的cur_max大于或者等于0,cur_max = cur_max + a[j+1]。

每一轮需要比较cur_max和记录的max值进行比较更新。

此算法的时间复杂度为O(N) 空间复杂度为O(1);


源码:

int MaxSum( const int* numbers, unsigned int N )
{
assert( numbers );

int max = numbers[0];
int cur_max = max;

for ( int i=1; i<N; i++ )
{
if( cur_max < 0 )
cur_max = 0;
cur_max += numbers[i];
if( cur_max > max )
max = cur_max;
}

return max;
}

void main()
{
int nums[] = {-2,5,3,-6,4,-8,6};
//int nums[] = {0,-2,3,5,-1,2};
cout << MaxSum( nums, sizeof(nums) / sizeof(int) ) << endl;
system("pause");
}
http://blog.csdn.net/zhongjiekangping/article/details/6855021
《编程之美》里面对求一维,二维的都进行了讲解。 
1、一维中用动态规划可以使时间复杂度降到O(n). 
   思想:考虑数组中A[0],与最大的一段数组(A[i],...A[j])的关系 
         (1)、当0=i=j时,元素A[0]本身构成最大的一段 
         (2)、当0=i<j时,和最大的一段以 A[0]开始 
         (3)、当0<i时,元素A[0]与和最大一段没有关系 
   假设已经知道(A[1],...A[n-1])中和最大的一段数组之和为All[1],并且已经知道(A[1],...,A[n-1])中包含A[1]的和最大一段为start[1],那么A[0]到A[n-1]中和最大的一段为max(A[0],A[0]+start[1],All[1]) 
   
   动态规划总是这样,分析最后的结果,然后累加中间步骤的小结果们。 
C代码 复制代码 收藏代码
  1. int max(int x,int y){   
  2.     return (x > y) ? x : y;   
  3. }   
  4. int maxSum(int* A, int n){   
  5.     start[n-1] = A[n-1];   
  6.     All[n-1] = A[n-1];   
  7.     for(i = n-2; i>=0; i--){   
  8.         start[i] = max(A[i], A[i]+start[i+1]);   
  9.         all[i] = max(start[i],all[i+1]);   
  10.     }   
  11. }   return all[0];  
[c] view plaincopy
  1. int max(int x,int y){  
  2.     return (x > y) ? x : y;  
  3. }  
  4. int maxSum(int* A, int n){  
  5.     start[n-1] = A[n-1];  
  6.     All[n-1] = A[n-1];  
  7.     for(i = n-2; i>=0; i--){  
  8.         start[i] = max(A[i], A[i]+start[i+1]);  
  9.         all[i] = max(start[i],all[i+1]);  
  10.     }  
  11. }   return all[0];  


2、二维中,假设已经确定了矩形区域的上下边界,比如知道矩形区域的上下边界分别是第a行和第c行,现在要确定左右边界。 
 
转化为一个一维问题,可以把每一列中第a行和第c行之间的元素看成一个整体。即求数组(BC[1],...BC[M])中和最大的一段,其中B[i] = B[a][i]+...B[c][i]. 

3、扩展问题;如果是三维数组呢? 
我的问题是如果是高维数组呢? 

---------------------------- 
其实不管多高维,都可以用二维数组的解法来解,三维数组就分解为两个二维平面。。对应于二维中的第a行和第c行,三维中就是第a个平面和第c平面;对应于二维中BC的数组,三维中就是BC平面。。 
同样,四维就分为两个三维来做。。。