经典算法——求最大子序列和(2)

这是我面试的时候想到的算法的实现,使用分治法,算法复杂度为O(n*log(n))。算法描述如下:
     对于每一个划分子序列需要获取4个数值:
         sum(子序列和)、maxSum(最大子序列和)、lMaxSum(最大的含有最左侧节点的子序列和)、rMaxSum(最大的含有最右侧节点的子序列和)
     递归算法(res为需要运算的结果,lRes、rRes分别为该段的左右划分):
         res->sum = lRes->sum + rRes->sum;
         res->lMaxSum = max(lRes->lMaxSum, lRes->sum + rRes->lMaxSum);
         res->rMaxSum = max(rRes->rMaxSum, rRes->sum + lRes->rMaxSum);
         res->maxSum = max3(lRes->maxSum, rRes->maxSum, lRes->rMaxSum + rRes->lMaxSum);

全部源代码如下:

/*
 * 子序列结果 
 
*/

typedef 
struct  _SubSequenceRes 
{
    
int sum;
    
int maxSum;
    
int lMaxSum;
    
int rMaxSum;
}
 SubSequenceRes;

/*
 * 求两数中的最大值 
 
*/

static   int  max( int  m,  int  n)
{
    
return (m>n) ? m : n;
}


/*
 * 求三数中的最大值 
 
*/

static   int  max3( int  a,  int  b,  int  c)
{
    
return max(a, max(b, c));
}


/*
 * 创建子序列结果结构 
 
*/

static  SubSequenceRes  *  newSubSequenceRes()
{
    
return (SubSequenceRes *)malloc(sizeof(SubSequenceRes));
}


/*
 * 释放子序列结果结构 
 
*/

static   void  deleteSubSequenceRes(SubSequenceRes  * pointer)
{
    free(pointer);
}


/*
 * 循环解析子序列,获得子序列结果结构
 
*/

static  SubSequenceRes  *  _maxSubSequenceSum4( int  a[],  int  left,  int  right)
{
    
int center;
    
int leftMaxSum;
    
int rightMaxSum;
    SubSequenceRes 
*res = newSubSequenceRes();
    SubSequenceRes 
*lRes, *rRes;
    
    
if (left == right)
    
{
        res
->sum = res->maxSum = res->lMaxSum = res->rMaxSum = a[left];
    }

    
else
    
{
        center 
= (left + right) >> 1;    /* center = (left + right) / 2; */
        lRes 
= _maxSubSequenceSum4(a, left, center);
        rRes 
= _maxSubSequenceSum4(a, center + 1, right);
        res
->sum = lRes->sum + rRes->sum;
        res
->lMaxSum = max(lRes->lMaxSum, lRes->sum + rRes->lMaxSum);
        res
->rMaxSum = max(rRes->rMaxSum, rRes->sum + lRes->rMaxSum);
        res
->maxSum = max3(lRes->maxSum, rRes->maxSum, lRes->rMaxSum + rRes->lMaxSum);
        deleteSubSequenceRes(lRes);
        deleteSubSequenceRes(rRes);
    }

    
    
return res;
}


/*
 * 分治法实现:
 *     对于每一个划分子序列需要获取4个数值:
 *         sum(子序列和)、maxSum(最大子序列和)、lMaxSum(最大的含有最左侧节点的子序列和)、rMaxSum(最大的含有最右侧节点的子序列和) 
 *     递归算法(res为需要运算的结果,lRes、rRes分别为该段的左右划分): 
 *         res->sum = lRes->sum + rRes->sum;
 *         res->lMaxSum = max(lRes->lMaxSum, lRes->sum + rRes->lMaxSum);
 *         res->rMaxSum = max(rRes->rMaxSum, rRes->sum + lRes->rMaxSum);
 *         res->maxSum = max3(lRes->maxSum, rRes->maxSum, lRes->rMaxSum + rRes->lMaxSum);
 
*/

int  maxSubSequenceSum4( int  a[],  int  len)
{
    SubSequenceRes 
* res = _maxSubSequenceSum4(a, 0, len - 1);
    
int result = res->maxSum;
    deleteSubSequenceRes(res);
    
return result;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值