面试题(十)连续子数组的最大和、最大差

来源:互联网 发布:sql 除后求和 编辑:程序博客网 时间:2024/06/06 01:16

这个题目是个很常见的面试题,主要的解法之一是DP方法,也是最简单的方法

这个问题的DP解答核心在于维护一个END[i],END[i]代表以pArray[i]为结尾的子数组的最大和。

已经假定了pArray[i]是这个子数组的最后一个数字,那么END[i-1]+Parray[i]<=END[i],当END[i-1]大于等于0时,等号成立,这是整个解法的思想

代码如下

int getMaxSum(int *pArray,int nSize){if (pArray==NULL){return -1;}intnSum=0;int nMaxSum=-INF;for (int i=0;i<nSize;i++){if (nSum<0){nSum=pArray[i];}else{nSum+=pArray[i];}if (nSum>nMaxSum){nMaxSum=nSum;}}return nMaxSum;}
关于最大差,有道google面试题:

给定一个数组,我们可以找到两个不相交的,并且是连续的子数组A和B,A中的数字和为sum(A),B中的数字和为sum(B),找到这样的A和B,满足Sum(A)-sum(B)的绝对值是最大的。

例如:[2 -1 -2 1 -4 2 8]划分为A=[-1 -2 1 -4] B=[2,8] 最大值为16。
可以使用基于划分的方法,求的这个划分点左边数组的最大和,右边数组的最小和,或者相反,最后求差,最后遍历整个划分策略

代码如下

int getMaxDiff(int *pArray,int nSize){if (pArray==NULL){return -INF;}int *pEndMax=new int[nSize];//从左往右int *pEndMin=new int[nSize];//从左往右int *pStartMax=new int[nSize];//从右往左int *pStartMin=new int[nSize];//从右往左pEndMin[0]=pArray[0];pEndMax[0]=pArray[0];for (int i=1;i<nSize;i++){if (pEndMax[i-1]<=0){pEndMax[i]=pArray[i];}else{pEndMax[i]=pEndMax[i-1]+pArray[i];}if (pEndMin[i-1]<=0){pEndMin[i]=pEndMin[i-1]+pArray[i];}else{pEndMin[i]=pArray[i];}}pStartMin[nSize-1]=pArray[nSize-1];pStartMax[nSize-1]=pArray[nSize-1];for (int i=nSize-2;i>=0;--i){if (pStartMax[i+1]>=0){pStartMax[i]=pStartMax[i+1]+pArray[i];}elsepStartMax[i]=pArray[i];if (pStartMin[i+1]<0){pStartMin[i]=pStartMin[i+1]+pArray[i];}elsepStartMin[i]=pArray[i];}int nMaxdiff=pEndMax[0]-pStartMin[1];for (int partitionIndex=0;partitionIndex<nSize-1;partitionIndex++){int diff=abs(pEndMax[partitionIndex]-pStartMin[partitionIndex+1]);if (diff>nMaxdiff){nMaxdiff=diff;}diff=abs(pEndMin[partitionIndex]-pStartMax[partitionIndex+1]);if (diff>nMaxdiff){nMaxdiff=diff;}}delete []pEndMax;delete []pEndMin;delete []pStartMax;delete []pStartMin;return nMaxdiff;}




0 0
原创粉丝点击