最大子段和问题

最大子段和算法
/**
 * 问题: 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],
 * 求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。
 * 当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为: 
 * Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n 
 * 例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,
 * 最大子段和为20。
 */
var a = [-2, 11, -4, 13, -5, -2];

console.log(maxsub(a));

// 分治法
function maxsub(a) {
    function _maxsub(a, left, right) {
        var sum, left_sum, right_sum;
        var left_max, right_max;
        var i, center = Math.floor((left+right)/2);

        if (left === right) {
            return a[left] > 0 ? a[left] : 0;
        }

        left_sum = _maxsub(a, left, center);
        right_sum = _maxsub(a, center+1, right);
        sum = 0;
        left_max = 0;
        for (i = center; i >= left; i--) {
            sum += a[i];
            if (sum > left_max) {
                left_max = sum;
            }
        }
        sum = 0;
        right_max = 0;
        for (i = center + 1; i <= right; i++) {
            sum += a[i];
            if (sum > right_max) {
                right_max = sum;
            }
        }
        sum = right_max + left_max;
        if (sum < left_sum) {
            sum = left_sum;
        }
        if (sum < right_sum) {
            sum = right_sum;
        }
        return sum;
    }
    return _maxsub(a, 0, a.length-1);
}

  

  

// 动态规划法
function maxsub(a) {
    var max, n = a.length, i, b = new Array(n);    
    max = b[0] = a[0];
    for (i = 1; i < n; i++) {
        b[i] = b[i-1]>0 ? b[i-1]+a[i] : a[i];
        if (b[i]>max) {
            max = b[i];
        }
    }
    return max;
}

最优解:

function maxsub(a) {
    var thisSum, maxSum;
    thisSum = maxSum = 0;
    for (var j = 0; j < a.length; j++) {
        thisSum += a[j];
        if (thisSum > maxSum) {
            maxSum = thisSum;
        } else if (thisSum < 0) {
            thisSum = 0;
        }
    }
    return maxSum;
}

  

  

转载于:https://www.cnblogs.com/mingzhanghui/p/9249912.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值