求数组子数组和最大值

13 篇文章 0 订阅

来源http://blog.csdn.net/huangxy10/article/details/8087430

来源:编程之美2.24


一些典型的测试用例:

[1,-2,3,5,-3,2]   max=8

[0,-2,3,5,-1,2]    max =9

[-2,-4,-3]      max=-2


这是一个动态规划问题,设当前扫描到arr[i]

则summax= max( arr[i], maxendinghere, maxsofar);

其中maxendinghere = max( maxendinghere+arr[i], arr[i]).


所以时间复杂度O(n),空间复杂度O(1).

  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. //dp算法  
  5. int maxsum(int *arr,const size_t len)  
  6. {  
  7.     if( len<0 )return 0;  
  8.     int maxendinghere = arr[0];  
  9.     int maxsofar = arr[0];  
  10.     for(size_t  i=1;i<len;++i)  
  11.     {   
  12.         maxendinghere = max(maxendinghere+arr[i],arr[i]);  
  13.         maxsofar = max(maxsofar,maxendinghere);         
  14.     }  
  15.     return maxsofar;  
  16. }   
  17. int main()  
  18. {  
  19.     int arr[] = {-31,-41,4,-3,4,-1,-97,-93,-23,-84};  
  20.     cout<<"MAX:"<<maxsum(arr, sizeof(arr)/sizeof(int));  
  21.     return 0;  
  22. }  

  1. 以下是另一种解法,并输出子数组所在位置
    #include <stdio.h>
    #include <iostream>
    #include <assert.h>
    
    using namespace std;
    int start_index;
    int end_index;
    int maxsum(int* parray,int length)
    {
    	assert(parray!=NULL&&0!=length);
    	int nstart=parray[length-1];
    	int nall=parray[length-1];
    	int ret=0;
    	
    	for (int i=length-2;i>=0;i--)
    	{
    		if (nstart<0)
    		{
    			nstart=0;
    		}
    		nstart+=parray[i];
    		if (nstart>nall)
    		{
    			if (ret==0)
    			{
    				end_index=i;
    			}
    			nall=nstart;
    			ret++;
    			start_index=i;
    		}
    		
    	}
    	
    	return nall;
    }
    void test()
    {
    	int array[]={1,3,-9,6,-4,5,7,-1};
    	int sum=maxsum(array,8);
    	for (int i=start_index;i<=end_index;i++)
    	{
    		cout<<"("<<array[i]<<")"<<"+";
    	}
    	cout<<"="<<sum<<endl;
    }
    int main()
    {
    	test();
    	system("pause");
    	return 0;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值