zoukankan      html  css  js  c++  java
  • 7、给定n个序列,求相邻的k个数之和为最大

    1、问题描述:给定n个数,求相邻的k个数之和为最大。要求给出复杂度较小的一种算法

    再解决这个问题前,先了解一下类似的常见问题。

    2、给定一串数字(可正可负的int,放在数组Num里),要求找到起始位置start和终止位置end,使得从start位置到end位置的所有数字之和最大,返回这个最大值max

    算法思想:用动态规划算法实现。

    iMaxSum 为以 iNumPar[i] 终止且包含 iNumPar[i] 的最大序列的和,有:

       iMaxSum  =  iNumPar[0];

       iMaxSum  =  iMaxSum > 0 ? iMaxSum + iNumPar[i+1] : iNumPar[i+1];

       其中,i = 0,1,...

    那么和iMaxSum 就是 iNumPar[0] ... iNumPar[n] 中最大的一个序列。

    算法的时间复杂度为O(n)

    示例代码

    #include <iostream>
    
    using namespace std;
    
    void FindTheMaxSum(int iNumPar[], const int iSize, int &ibegin, int &iend, int &iMaxSum)
    {
    	ibegin = iend = 0;
    	int iTemSum = iNumPar[0], iStart = 0;
    	iMaxSum = iTemSum;
    	for (int i = 1; i < iSize; ++i)
    	{
    		if (iTemSum > 0)
    		{
    			iTemSum = iTemSum + iNumPar[i];
    		}
    		else
    		{
    			iTemSum = iNumPar[i];
    			iStart = i;
    		}
    		
    		if (iTemSum > iMaxSum) //更新结果
    		{
    			iMaxSum = iTemSum;
    			ibegin = iStart;
    			iend = i;
    		}
    	}
    }
    
    int main()
    {
        int ibegin = 0, iend = 0, iResult = 0, iCount = 0;
    	int iNum[] = {-1, -2, -3, -4, 0, 1, 2, 3, 4, 5, -20, 40, -3};
    	iCount = sizeof(iNum)/sizeof(iNum[0]);
        FindTheMaxSum(iNum, iCount, ibegin, iend, iResult);
    	cout << ibegin <<" "<< iend <<" "<< iResult <<endl;
    	return 1;
    }
    

    3、最容易想到的就是穷举搜索。在n个序列中求出每k个连续序列的值,进行比较。

    示例代码

    #include <iostream>
    
    using namespace std;
    
    void FindTheMaxKSum(int iNumPar[], const int iSize, int iK, int &ibegin, int &iend, int &iMaxSum)
    {
    //iK指出求最大各子序列的长度
    	int iTemMaxKsum = 0;
    	for (int i = 0; i < iK; ++i)
    	{
    		iTemMaxKsum += iNumPar[i];
    	}
    	iMaxSum = iTemMaxKsum;
    	
    	int iStart = ibegin = 0, iOver = iend = iK - 1;
    	for (int i = 1; (i < iSize) && ((iSize - i) >= iK); ++i)
    	{
    		iTemMaxKsum = 0;
    		for (int j = i; ((j - i) < iK) && (j < iSize); ++j)
    		{
    			iTemMaxKsum += iNumPar[j];
    		}
    
    		if (iTemMaxKsum > iMaxSum)
    		{
    			iMaxSum = iTemMaxKsum;
    			ibegin = i;
    			iend = i + iK - 1;
    		}
    	}
    }
    
    int main()
    {
        int ibegin = 0, iend = 0, iResult = 0, iCount = 0;
    	int iNum[] = {-1, -2, 4, 5, 6, 1, 2, 3, 4, -4, -20, 40, -3};
    	iCount = sizeof(iNum)/sizeof(iNum[0]);
        FindTheMaxKSum(iNum, iCount, 3, ibegin, iend, iResult);
    	cout << ibegin <<" "<< iend <<" "<< iResult <<endl;
    	return 1;
    }
    

    由上可见,复杂度为O(iK + n*k)

    那么有没有更好的方法呢?优化的方法就是把循环体内的相加循环去掉。

    示例代码

    #include <iostream>
    
    using namespace std;
    
    void FindTheMaxKSum(int iNumPar[], const int iSize, int iK, int &ibegin, int &iend, int &iMaxSum)
    {
    //iK指出求最大各子序列的长度
    
    	int *pTempSum = new int[iSize];
    	pTempSum[0] = iNumPar[0];
    	for (int i = 1; i < iSize; i++)
    	{
    		pTempSum[i] = pTempSum[i - 1] + iNumPar[i]; 
    	}
    	
    	int iStart = ibegin = 0;
    	ibegin = 0;
    	iend = iK - 1;
    	iMaxSum = pTempSum[iend];
    
    	for (int i = 1, j = iK; j < iSize; ++i, ++j)
    	{
    		if ((pTempSum[j] - pTempSum[i - 1]) > iMaxSum)
    		{
    			iMaxSum = pTempSum[j] - pTempSum[i - 1];
    			ibegin = i;
    			iend = j;
    		}
    	}
    delete pTempSum[];
    }
    
    int main()
    {
        int ibegin = 0, iend = 0, iResult = 0, iCount = 0;
    	int iNum[] = {-1, -2, 4, 5, 6, 1, 2, 3, 4, -4, -20, 40, -3};
    	iCount = sizeof(iNum)/sizeof(iNum[0]);
        FindTheMaxKSum(iNum, iCount, 3, ibegin, iend, iResult);
    	cout << ibegin <<" "<< iend <<" "<< iResult <<endl;
    	return 1;
    }
    

        由上可见,程序复杂度为O(n)n为问题规模。

    参考

    [1]更多的数学说明:

    http://www.cnblogs.com/Jason_Yao/archive/2009/09/27/1574713.html

    [2]CSDN论坛中的讨论

    http://topic.csdn.net/u/20110402/12/795e568e-b590-4fb0-8a4d-dba8b408441f.html?1021658511

  • 相关阅读:
    Javascript FP-ramdajs
    微信小程序开发
    SPA for HTML5
    One Liners to Impress Your Friends
    Sass (Syntactically Awesome StyleSheets)
    iOS App Icon Template 5.0
    React Native Life Cycle and Communication
    Meteor framework
    RESTful Mongodb
    Server-sent Events
  • 原文地址:https://www.cnblogs.com/mydomain/p/2003320.html
Copyright © 2011-2022 走看看